패션 MNIST 데이터셋: 10개 클래스, 28X28픽셀, 흑백, 60000개
-> 각 픽셀은 0~255 사이의 정숫값 가짐
load_data() : 훈련 데이터, 테스트 데이터 나눠서 반환
np.unique : 함수 레이블 당 샘플 개수 확인

-> 0~9까지 레이블마다 정확히 6000개의 샘플이 들어 있음
reshape : 차원을 줄여줌 (2차원 -> 1차원)

10개의 클래스는 모두 다른 가중치(w)를 사용함

출력층이 1개인 인공 신경망은 로지스틱 회귀와 비슷함

출력층 : 신경망의 최종 값
뉴런 : 인공 신경망에서 z값을 계산하는 단위
유닛 = 뉴런
입력층 : 입력데이터(픽셀값)
밀집층 : 가장 기본이 되는 층
밀집층 = 완전 연결층
데이터 많음 -> 검증 안정
검증 세트를 나눔


10 -> 뉴런 개수
activation -> 뉴런의 출력에 적용할 함수
input_shape -> 입력의 크기(튜플)
Sequential : 신경망 모델 만드는 클래스

compile : 모델 설정
loss : 손실함수
'sparse_categorical_crossentropy' : 정수로된 타깃데이터를 사용하고 싶을 때
원-핫 인코딩 : 타깃값을 해당 클래스만 1이고 나머지는 모두 0인 배열로 만드는 것
evaluate : 평가

사이킷런 모델은 한번에 모델을 생성하고 케라스 모델은 층 생성, 모델 생성, 모델 설정을 따로 한다는 점에서 차이가 있고 훈련과 평가는 비슷함
2개의 층 : 은닉층과 출력층 1개씩으로 이루어진 인공 신경망(입력층은 층으로 안봄)

은닉층에서 선형적인 산술 계산만 수행한다면 수행 역할이 없는 셈임
선형 계산을 적당하게 비선형적으로 비틀어 주어야 함
활성화 함수가 그 역할을 함

summary() : 층에 대한 유용한 정보를 제공
케라스 모델의 fit()메소드에 훈련 데이터를 주입하면 미니배치 경사 하강법을 함
batch_size매개변수로 크기를 바꿀 수 있음
-> 샘플 개수를 고정하지 않고 어떤 배치에도 유연하게 대응하기 위해 None으로 설정

Param#은 모델 파라미터 개수
784개(입력층 뉴런) X 100개(은닉층 뉴런) + 100개(절편) = 78500개
100개(은닉층 뉴런) X 10개(출력층 뉴런) + 10개(절편) = 1010개

->Sequential클래스의 생성자 안에서 바로 Dense클래스이 객체를 만드는 경우

->add()메소드를 사용하여 바로 전달
add()메소드를 사용하면 동적으로 층을 선택하여 추가할 수 있음
입력이 양수일 경우 입력 통과, 음수일 경우 0

Flatten클래스 : 배치 차원을 제외하고 입력 차원을 모두 일렬로 펼치는 역할을 함

-> summary()를 하면 모델 매개변수 개수는 0으로 나옴
: 케라스가 제공하는 다양한 종류의 경사 하강법
옵티마이저는 하이퍼 파라미터임

위 아래는 같은 역할을 함

SGD 클래스의 학습률 기본값이 0.01이고 이를 learning_rate매개변수로 바꿀 수 있음


적응적 학습률 옵티마이저는 RPSprop, Adam, Adagrad이고 이는 가파를 때는 많이 내려가고 최저점에 가까워지면 조금씩 내려가는 방식임
