imports

import tensorflow as tf
import tensorflow.experimental.numpy as tnp
tnp.experimental_enable_numpy_behavior()
import matplotlib.pyplot as plt
import numpy as np
tf.config.experimental.list_physical_devices()
[PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU'),
 PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
%load_ext tensorboard

CNN

CONV의 역할

- 데이터생성 (그냥 흑백대비 데이터)

_X1 = tnp.ones([50,25])*10 
_X1
<tf.Tensor: shape=(50, 25), dtype=float64, numpy=
array([[10., 10., 10., ..., 10., 10., 10.],
       [10., 10., 10., ..., 10., 10., 10.],
       [10., 10., 10., ..., 10., 10., 10.],
       ...,
       [10., 10., 10., ..., 10., 10., 10.],
       [10., 10., 10., ..., 10., 10., 10.],
       [10., 10., 10., ..., 10., 10., 10.]])>
_X2 = tnp.zeros([50,25])*10 
_X2
<tf.Tensor: shape=(50, 25), dtype=float64, numpy=
array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]])>
tf.concat([_X1,_X2],axis=1)
<tf.Tensor: shape=(50, 50), dtype=float64, numpy=
array([[10., 10., 10., ...,  0.,  0.,  0.],
       [10., 10., 10., ...,  0.,  0.,  0.],
       [10., 10., 10., ...,  0.,  0.,  0.],
       ...,
       [10., 10., 10., ...,  0.,  0.,  0.],
       [10., 10., 10., ...,  0.,  0.,  0.],
       [10., 10., 10., ...,  0.,  0.,  0.]])>
plt.imshow(tf.concat([_X1,_X2],axis=1),cmap='gray')
<matplotlib.image.AxesImage at 0x7fdb88415000>
_noise = tnp.random.randn(50*50).reshape(50,50)
_noise
<tf.Tensor: shape=(50, 50), dtype=float64, numpy=
array([[-0.51170252,  0.44488448, -0.37768718, ...,  0.31721451,
        -2.51327619,  0.52484648],
       [-0.4941939 , -1.09514349,  1.25396721, ..., -0.23194   ,
        -0.71051373, -0.69419095],
       [-0.45022513, -2.02717269,  0.92595479, ...,  1.78765173,
         0.14056303,  0.520452  ],
       ...,
       [-0.14080382, -2.29286879, -0.80367313, ..., -0.59715722,
         0.54068818,  1.93618727],
       [-1.03439842, -0.940278  ,  0.73305531, ..., -0.62282159,
         1.45165231,  0.66823899],
       [-3.05820828,  0.85240415,  0.72343724, ...,  1.09404843,
         1.23579105,  1.3008287 ]])>
XXX = tf.concat([_X1,_X2],axis=1) + _noise
XXX=XXX.reshape(1,50,50,1) # conv를 위해 shape을 맞춰주었다.
plt.imshow(XXX.reshape(50,50),cmap='gray')
<matplotlib.image.AxesImage at 0x7fdb88463be0>

- conv layer 생성

conv = tf.keras.layers.Conv2D(2,(2,2)) 
conv.weights # 처음에는 가중치가 없음 
[]
conv(XXX) # 가중치를 만들기 위해서 XXX를 conv에 한번 통과시킴
conv.weights # 이제 가중치가 생김
[<tf.Variable 'conv2d/kernel:0' shape=(2, 2, 1, 2) dtype=float32, numpy=
 array([[[[-0.45586333, -0.1047467 ]],
 
         [[ 0.6862492 , -0.4972797 ]]],
 
 
        [[[-0.13820118,  0.20424747]],
 
         [[ 0.3288589 , -0.11026746]]]], dtype=float32)>,
 <tf.Variable 'conv2d/bias:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)>]

- 가중치의 값을 확인해보자.

conv.weights[0] # kernel에 해당하는것 
<tf.Variable 'conv2d/kernel:0' shape=(2, 2, 1, 2) dtype=float32, numpy=
array([[[[-0.45586333, -0.1047467 ]],

        [[ 0.6862492 , -0.4972797 ]]],


       [[[-0.13820118,  0.20424747]],

        [[ 0.3288589 , -0.11026746]]]], dtype=float32)>
conv.weights[1] # bias에 해당하는것 
<tf.Variable 'conv2d/bias:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)>

bias가 2개 들어가있네!

w1 참고 그림

- 필터값을 원하는 것으로 변경해보자.

w0 = [[0.25,0.25],[0.25,0.25]] # 잡티를 제거하는 효과를 준다. (평균이 되니까!)
w1 = [[-1.0,1.0],[-1.0,1.0]] # 경계를 찾기 좋아보이는 필터이다. (엣지검출)
np.array(w0).reshape(2,2,1,1)
array([[[[0.25]],

        [[0.25]]],


       [[[0.25]],

        [[0.25]]]])
np.array(w1).reshape(2,2,1,1)
array([[[[-1.]],

        [[ 1.]]],


       [[[-1.]],

        [[ 1.]]]])
w=np.concatenate([np.array(w0).reshape(2,2,1,1),np.array(w1).reshape(2,2,1,1)],axis=-1)
w
array([[[[ 0.25, -1.  ]],

        [[ 0.25,  1.  ]]],


       [[[ 0.25, -1.  ]],

        [[ 0.25,  1.  ]]]])
b= np.array([0.0,0.0])
b
array([0., 0.])
conv.set_weights([w,b])
conv.get_weights()
[array([[[[ 0.25, -1.  ]],
 
         [[ 0.25,  1.  ]]],
 
 
        [[[ 0.25, -1.  ]],
 
         [[ 0.25,  1.  ]]]], dtype=float32),
 array([0., 0.], dtype=float32)]
  • 첫번째는 평균을 구하는 필터,
  • 두번째는 엣지를 검출하는 필터

- 필터를 넣은 결과를 확인

채널 2개(1,49,49,2) 나오니까 나눠서 보자

XXX0=conv(XXX)[...,0] # 채널0
XXX0
<tf.Tensor: shape=(1, 49, 49), dtype=float32, numpy=
array([[[ 9.5859613e+00,  1.0056505e+01,  1.0326652e+01, ...,
          5.6875817e-02, -7.8462887e-01, -8.4828353e-01],
        [ 8.9833164e+00,  9.7644024e+00,  1.0720357e+01, ...,
          4.0478933e-01,  2.4644026e-01, -1.8592241e-01],
        [ 9.5075359e+00,  9.6883612e+00,  1.0516663e+01, ...,
          8.2350314e-02,  2.6497537e-01,  4.3067247e-01],
        ...,
        [ 9.3961983e+00,  9.1817837e+00,  9.9334126e+00, ...,
         -2.5907221e-01, -9.5353723e-03,  4.6619147e-01],
        [ 8.8979130e+00,  9.1740589e+00,  1.0204453e+01, ...,
          2.3932981e-01,  1.9309041e-01,  1.1491916e+00],
        [ 8.9548798e+00,  1.0342155e+01,  1.0008765e+01, ...,
          1.7812608e-01,  7.8966755e-01,  1.1641278e+00]]], dtype=float32)>
XXX1=conv(XXX)[...,1] # 채널1
XXX1
<tf.Tensor: shape=(1, 49, 49), dtype=float32, numpy=
array([[[ 0.35563755,  1.5265388 , -0.44595432, ..., -0.05695425,
         -3.3090644 ,  3.0544453 ],
        [-2.177897  ,  5.302238  , -1.4784145 , ...,  1.4922662 ,
         -2.1256626 ,  0.39621174],
        [-4.14058   ,  4.8638835 , -1.5506802 , ...,  1.1737798 ,
         -0.44327974,  1.1060681 ],
        ...,
        [-1.7283144 ,  0.8706579 ,  2.1358538 , ...,  2.2917542 ,
         -1.2936069 ,  3.1965141 ],
        [-2.0579443 ,  3.162529  ,  0.9590483 , ..., -3.3972769 ,
          3.2123194 ,  0.6120858 ],
        [ 4.004733  ,  1.5443659 , -2.877925  , ...,  0.2299493 ,
          2.2162166 , -0.7183757 ]]], dtype=float32)>

- 각 채널을 시각화

fig, ((ax1,ax2),(ax3,ax4)) = plt.subplots(2,2)
ax1.imshow(XXX.reshape(50,50),cmap='gray')
<matplotlib.image.AxesImage at 0x7fdb8828a5c0>
ax3.imshow(XXX0.reshape(49,49),cmap='gray')
<matplotlib.image.AxesImage at 0x7fdb88552470>
ax4.imshow(XXX1.reshape(49,49),cmap='gray')
<matplotlib.image.AxesImage at 0x7fdb88289d50>
fig
  • 2사분면: 원래이미지
  • 3사분면: 원래이미지 -> 평균을 의미하는 conv적용
  • 4사분면: 원래이미지 -> 엣지를 검출하는 conv적용

- conv(XXX)의 각 채널에 한 번 더 conv를 통과시켜보자

XXX0.shape, XXX1.shape
(TensorShape([1, 49, 49]), TensorShape([1, 49, 49]))
conv(XXX0.reshape(1,49,49,1))[...,0] ### XXX0 -> 평균필터 <=> XXX -> 평균필터 -> 평균필터 
conv(XXX0.reshape(1,49,49,1))[...,1] ### XXX0 -> 엣지필터 <=> XXX -> 평균필터 -> 엣지필터 
conv(XXX1.reshape(1,49,49,1))[...,0] ### XXX1 -> 평균필터 <=> XXX -> 엣지필터 -> 평균필터 
conv(XXX1.reshape(1,49,49,1))[...,1] ### XXX1 -> 엣지필터 <=> XXX -> 엣지필터 -> 엣지필터 
<tf.Tensor: shape=(1, 48, 48), dtype=float32, numpy=
array([[[  8.651036  ,  -8.753145  ,   2.0467367 , ...,   1.7177694 ,
          -6.870039  ,   8.885384  ],
        [ 16.484598  , -13.195216  ,   5.1244392 , ...,   2.4541578 ,
          -5.234988  ,   4.0712223 ],
        [ 13.650472  , -10.372585  ,   4.8081884 , ...,  -4.5104175 ,
           0.12856537,   1.5617114 ],
        ...,
        [  0.2099638 ,   4.598176  ,   0.42708588, ...,  14.179796  ,
         -14.57027   ,  13.218005  ],
        [  7.8194456 ,  -0.9382849 ,  -3.1723719 , ...,  -0.36768866,
           3.0242352 ,   1.8898873 ],
        [  2.760106  ,  -6.6257715 ,   2.1411648 , ...,  -4.7194347 ,
           8.595863  ,  -5.534826  ]]], dtype=float32)>
fig,ax =plt.subplots(3,4)
ax[0][0].imshow(XXX.reshape(50,50),cmap='gray') # 원래 이미지
<matplotlib.image.AxesImage at 0x7fdb80111d80>
ax[1][0].imshow(XXX0.reshape(49,49),cmap='gray') # 원래 이미지 -> 평균필터 
ax[1][2].imshow(XXX1.reshape(49,49),cmap='gray') # 원래 이미지 -> 엣지필터
<matplotlib.image.AxesImage at 0x7fdb884aeb00>
ax[2][0].imshow(conv(XXX0.reshape(1,49,49,1))[...,0].reshape(48,48),cmap='gray') # 원래이미지 -> 평균필터 
ax[2][1].imshow(conv(XXX0.reshape(1,49,49,1))[...,1].reshape(48,48),cmap='gray') # 원래이미지 -> 엣지필터
ax[2][2].imshow(conv(XXX1.reshape(1,49,49,1))[...,0].reshape(48,48),cmap='gray') # 원래이미지 -> 평균필터 
ax[2][3].imshow(conv(XXX1.reshape(1,49,49,1))[...,1].reshape(48,48),cmap='gray') # 원래이미지 -> 엣지필터
<matplotlib.image.AxesImage at 0x7fdb80111c90>
fig.set_figheight(8)
fig.set_figwidth(16)
fig.tight_layout()
fig

평균 두 번 했더니 희미해지는 거 같아

엣지 두 번하는 것은 의미 없는 것 같아

- 요약

  • conv의 weight에 따라서 엣지를 검출하는 필터가 만들어지기도 하고 스무딩의 역할을 하는 필터가 만들어지기도 한다. 그리고 우리는 의미를 알 수 없지만 어떠한 역할을 하는 필터가 만들어질 것이다.
  • 이것들을 조합하다보면 우연히 이미지를 분류하기에 유리한 특징을 뽑아내는 weight가 맞춰질 수도 있겠다.
  • 채널수를 많이 만들고 다양한 웨이트조합을 실험하다보면 보다 복잡한 이미지의 특징을 추출할 수도 있을 것이다?
  • 컨볼루션 레이어의 역할 = 이미지의 특징을 추출하는 역할
XXX.shape
TensorShape([1, 50, 50, 1])
plt.imshow(conv(XXX.reshape(50,50).T.reshape(1,50,50,1))[...,1].reshape(49,49))
<matplotlib.image.AxesImage at 0x7fdb241814e0>
plt.imshow(conv(XXX.reshape(50,50).T.reshape(1,50,50,1))[...,0].reshape(49,49))
<matplotlib.image.AxesImage at 0x7fdb241c26e0>
  • 경계 없는 거랑 있는 거랑은 값을 다 더해서 큰 것만 골라내는 법으로 찾을 수 있음
  • 필터를 다르게 설정하면 경계를 다르게 가진 이미지를 구분해낼 수 있다.
    • 경계가 위처럼 등장할 것이니까!
    • 하지만 모든 필터가 이렇게 경계를 구분해 내는 것은 아니야, 우리는 기대를 할 뿐, 그 경계를 찾을 것이라는

- 참고: 스트라이드, 패딩

  • 스트라이드: 윈도우가 1칸씩 이동하는 것이 아니라 2~3칸씩 이동함
  • 패딩: 이미지의 가장자리에 정당한 값을 넣어서 (예를들어 0) 컨볼루션을 수행. 따라서 컨볼루션 연산 이후에도 이미지의 크기가 줄어들지 않도록 방지한다.

MAXPOOL

- 기본적역할: 이미지의 크기를 줄이는 것

  • 이미지의의 크기를 줄여야하는 이유? 어차피 최종적으로 10차원으로 줄어야하므로
  • 이미지의 크기를 줄이면서도 동시에 아주 크리티컬한 특징은 손실없이 유지하고 싶다~

이미지 크기를 줄여서 계산 덜 하게 하자( 더 빨리 돌아가게, 더 효율적으로)

- 점점 작은 이미지가 되면서 중요한 특징들은 살아남지만 그렇지 않으면 죽는다. (캐리커쳐 느낌)

- 평균이 아니라 max를 쓴 이유는? 그냥 평균보다 나을것이라고 생각했음..

  • 그런데 사실은 꼭 그렇지만은 않아서 최근에는 꼭 맥스풀링을 고집하진 않는 추세 (평균풀링도 많이씀)

특징을 압축하고, ..압축하고..

컴퓨터가 weight를 자동으로 찾는 maxpooling

CNN 아키텍처의 표현방법

- 아래와 같이 아키텍처의 다이어그램 형태로 표현하고 굳이 노드별로 이미지를 그리진 않음

- 물론 아래와 같이 그리는 경우도 있음

Discusstion about CNN

- 격자형태로 배열된 자료를 처리하는데 특화된 신경망이다.

  • 시계열 (1차원격자), 이미지 (2차원격자)

- 실제응용에서 엄청난 성공을 거두었다.

- 이름의 유래는 컨볼루션이라는 수학적 연산을 사용했기 때문

  • 컨볼루션은 조금 특별한 선형변환이다.

convolution neural network

- 신경과학의 원리가 심층학습에 영향을 미친 사례이다.

CNN의 모티브

- 희소성 + 매개변수의 공유

  • 다소 철학적인 모티브임
  • 희소성: 이미지를 분석하여 특징을 뽑아낼때 부분부분의 특징만 뽑으면 된다는 의미
  • 매개변수의 공유: 한 채널에는 하나의 역할을 하는 커널을 설계하면 된다는 의미 (스무딩이든 엣징이든). 즉 어떤지역은 스무딩, 어떤지역은 엣징을 할 필요가 없이 한채널에서는 엣징만, 다른채널에서는 스무딩만 수행한뒤 여러채널을 조합해서 이해하면 된다.

DNN에서는 픽셀마다 weight가 다 걸리니까 어느 부분에서 스무딩했는지, 엣징했는지 DNN의 출력결과를 통해 알아낼 수 있다.

- 매개변수 공유효과로 인해서 파라메터가 확 줄어든다.

(예시) (1,6,6,1) -> (1,5,5,2)

  • MLP방식이면 (36,50) 의 차원을 가진 매트릭스가 필요함 => 1800개의 매개변수 필요
  • CNN은 8개의 매개변수 필요

CNN 신경망의 기본구조

- 기본유닛

  • conv - activation - pooling
  • conv - conv - activation - pooling

모형의 성능을 올리기 위한 노력들

dropout

- 아래의 예제를 복습하자.

np.random.seed(43052)
x = np.linspace(0,1,100).reshape(100,1)
y = np.random.normal(loc=0,scale=0.01,size=(100,1))
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x7fdb2402dcc0>]

추정값이 직선이 나와서 이미 오버피팅이 예상되는 상태

tf.random.set_seed(43052)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(2048,activation='relu'))
net.add(tf.keras.layers.Dense(1))
net.compile(loss='mse',optimizer='adam')
net.fit(x,y,epochs=5000,verbose=0,batch_size=100)
<keras.callbacks.History at 0x7fdaf84544f0>
plt.plot(x,y)
plt.plot(x,net(x),'--')
[<matplotlib.lines.Line2D at 0x7fdaf83547c0>]

- train/test로 나누어서 생각해보자.

tf.random.set_seed(43052)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(2048,activation='relu'))
net.add(tf.keras.layers.Dense(1))
net.compile(loss='mse',optimizer='adam')
net.fit(x[:80],y[:80],epochs=5000,verbose=0,batch_size=80)
<keras.callbacks.History at 0x7fdaf839cfa0>
plt.plot(x,y)
plt.plot(x[:80],net(x[:80]),'--')
[<matplotlib.lines.Line2D at 0x7fdaf839e1d0>]
plt.plot(x,y)
plt.plot(x[:80],net(x[:80]),'--')
plt.plot(x[80:],net(x[80:]),'--')
[<matplotlib.lines.Line2D at 0x7fdaf851b730>]

오버피팅의 전형적안 예시

train, val-test 나눈다?

  • 조금 훈련하고 예측해보고 조금 훈련하고 예측해보고 이런 식!
  • train에서 추세를 따라가는게 좋은게 아니다 $\to$ 그냥 직선으로 핏하는거 이외에는 다 오버핏이다.

- 매 에폭마다 적당히 80%의 노드들을 빼고 학습하자 $\to$ 너무 잘 학습되는 문제는 생기지 않을 것이다 (과적합이 방지될것이다?)

tf.random.set_seed(43052)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(2048,activation='relu'))
net.add(tf.keras.layers.Dropout(0.8))
net.add(tf.keras.layers.Dense(1))
net.compile(loss='mse',optimizer='adam')
net.fit(x[:80],y[:80],epochs=5000,verbose=0,batch_size=80)
<keras.callbacks.History at 0x7fdaf8154370>
plt.plot(x,y)
plt.plot(x[:80],net(x[:80]),'--')
plt.plot(x[80:],net(x[80:]),'--')
[<matplotlib.lines.Line2D at 0x7fdaf816c100>]

- 드랍아웃에 대한 summary

  • 직관: 특정노드를 랜덤으로 off시키면 학습이 방해되어 오히려 과적합이 방지되는 효과가 있다 (그렇지만 진짜 중요한 특징이라면 랜덤으로 off 되더라도 어느정도는 학습될 듯)
  • note: 드랍아웃을 쓰면 오버핏이 줄어드는건 맞지만 완전히 없어지는건 아니다.
  • note: 오버핏을 줄이는 유일한 방법이 드랍아웃만 있는것도 아니며, 드랍아웃이 오버핏을 줄이는 가장 효과적인 방법도 아니다 (최근에는 dropout보다 batch nomalization을 사용하는 추세임)

중요한 특징은 이렇게 몇 개 빼고 해도 잘 나타날걸???

train / val / test

- data

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
X= x_train.reshape(-1,28,28,1)/255 ## 입력이 0~255 -> 0~1로 표준화 시키는 효과 + float으로 자료형이 바뀜 
y = tf.keras.utils.to_categorical(y_train)
XX = x_test.reshape(-1,28,28,1)/255
yy = tf.keras.utils.to_categorical(y_test)

255로 나누면

  • type이 float이 되고
  • 0 ~ 255를 0 ~ 1로 표준화도 되고
    • 표준화가 어느정도 되어 있어야 표현력이 높아진다.
    • $255 \times 1$ 보다 $1 \times \frac{1}{255}$가 나음

CNN 말고 DNN으로 받으려고 flatten이랑~

  • 이미지니까 categorical_crossentropy 써주자
net = tf.keras.Sequential()
net.add(tf.keras.layers.Flatten())
net.add(tf.keras.layers.Dense(50,activation='relu'))
net.add(tf.keras.layers.Dense(10,activation='softmax'))
net.compile(optimizer='adam',loss=tf.losses.categorical_crossentropy,metrics='accuracy')
x.shape
(100, 1)

20%를 valdation으로 빼서 학습을 시킬 것이다.

  • 아래 해석: 뺀 20%의 validation을 제외한 80%으로 학습을 한다.그것으로 20%를 맞춰보니 val_accuracy가 0.8~이러고 나왔다.
  • 한 40 정도에서는 끊어져야 하지 않을까? 그 이후에는 val_accuracy가 높아지지 않으니까.
    • 우리의 목표는 val_accuracy가 높아지는 것이니까 끊는게 좋겠다.
cb1 = tf.keras.callbacks.TensorBoard()
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=cb1,verbose=1) 

Epoch 1/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0739 - accuracy: 0.9743 - val_loss: 0.6479 - val_accuracy: 0.8736
Epoch 2/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0694 - accuracy: 0.9769 - val_loss: 0.6491 - val_accuracy: 0.8726
Epoch 3/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0692 - accuracy: 0.9769 - val_loss: 0.6616 - val_accuracy: 0.8723
Epoch 4/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0717 - accuracy: 0.9757 - val_loss: 0.6523 - val_accuracy: 0.8742
Epoch 5/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0689 - accuracy: 0.9770 - val_loss: 0.6482 - val_accuracy: 0.8738
Epoch 6/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0698 - accuracy: 0.9768 - val_loss: 0.6497 - val_accuracy: 0.8746
Epoch 7/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0703 - accuracy: 0.9766 - val_loss: 0.6696 - val_accuracy: 0.8728
Epoch 8/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0665 - accuracy: 0.9780 - val_loss: 0.6529 - val_accuracy: 0.8753
Epoch 9/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0680 - accuracy: 0.9770 - val_loss: 0.6757 - val_accuracy: 0.8720
Epoch 10/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0667 - accuracy: 0.9775 - val_loss: 0.6730 - val_accuracy: 0.8755
Epoch 11/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0673 - accuracy: 0.9786 - val_loss: 0.6627 - val_accuracy: 0.8748
Epoch 12/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0684 - accuracy: 0.9774 - val_loss: 0.6711 - val_accuracy: 0.8753
Epoch 13/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0657 - accuracy: 0.9786 - val_loss: 0.6694 - val_accuracy: 0.8739
Epoch 14/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0676 - accuracy: 0.9777 - val_loss: 0.7010 - val_accuracy: 0.8697
Epoch 15/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0695 - accuracy: 0.9771 - val_loss: 0.6836 - val_accuracy: 0.8742
Epoch 16/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0638 - accuracy: 0.9785 - val_loss: 0.6973 - val_accuracy: 0.8737
Epoch 17/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0653 - accuracy: 0.9781 - val_loss: 0.6705 - val_accuracy: 0.8750
Epoch 18/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0703 - accuracy: 0.9758 - val_loss: 0.7052 - val_accuracy: 0.8707
Epoch 19/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0634 - accuracy: 0.9792 - val_loss: 0.6814 - val_accuracy: 0.8717
Epoch 20/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0625 - accuracy: 0.9797 - val_loss: 0.6851 - val_accuracy: 0.8743
Epoch 21/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0679 - accuracy: 0.9765 - val_loss: 0.6870 - val_accuracy: 0.8724
Epoch 22/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0630 - accuracy: 0.9785 - val_loss: 0.7130 - val_accuracy: 0.8717
Epoch 23/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0718 - accuracy: 0.9752 - val_loss: 0.6983 - val_accuracy: 0.8733
Epoch 24/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0619 - accuracy: 0.9795 - val_loss: 0.6943 - val_accuracy: 0.8766
Epoch 25/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0678 - accuracy: 0.9772 - val_loss: 0.7039 - val_accuracy: 0.8684
Epoch 26/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0628 - accuracy: 0.9792 - val_loss: 0.6918 - val_accuracy: 0.8756
Epoch 27/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0594 - accuracy: 0.9810 - val_loss: 0.6963 - val_accuracy: 0.8730
Epoch 28/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0577 - accuracy: 0.9818 - val_loss: 0.7054 - val_accuracy: 0.8753
Epoch 29/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0592 - accuracy: 0.9809 - val_loss: 0.7049 - val_accuracy: 0.8750
Epoch 30/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0619 - accuracy: 0.9793 - val_loss: 0.7107 - val_accuracy: 0.8726
Epoch 31/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0656 - accuracy: 0.9780 - val_loss: 0.7041 - val_accuracy: 0.8771
Epoch 32/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0584 - accuracy: 0.9808 - val_loss: 0.7094 - val_accuracy: 0.8737
Epoch 33/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0612 - accuracy: 0.9790 - val_loss: 0.7399 - val_accuracy: 0.8709
Epoch 34/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0569 - accuracy: 0.9814 - val_loss: 0.7130 - val_accuracy: 0.8714
Epoch 35/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0586 - accuracy: 0.9806 - val_loss: 0.7255 - val_accuracy: 0.8724
Epoch 36/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0573 - accuracy: 0.9810 - val_loss: 0.7453 - val_accuracy: 0.8727
Epoch 37/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0611 - accuracy: 0.9794 - val_loss: 0.7260 - val_accuracy: 0.8745
Epoch 38/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0641 - accuracy: 0.9784 - val_loss: 0.7384 - val_accuracy: 0.8708
Epoch 39/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0600 - accuracy: 0.9802 - val_loss: 0.7185 - val_accuracy: 0.8742
Epoch 40/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0575 - accuracy: 0.9812 - val_loss: 0.7176 - val_accuracy: 0.8758
Epoch 41/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0576 - accuracy: 0.9804 - val_loss: 0.7303 - val_accuracy: 0.8733
Epoch 42/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0601 - accuracy: 0.9800 - val_loss: 0.7311 - val_accuracy: 0.8728
Epoch 43/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0581 - accuracy: 0.9802 - val_loss: 0.7477 - val_accuracy: 0.8745
Epoch 44/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0577 - accuracy: 0.9808 - val_loss: 0.7396 - val_accuracy: 0.8749
Epoch 45/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0551 - accuracy: 0.9820 - val_loss: 0.7456 - val_accuracy: 0.8713
Epoch 46/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0588 - accuracy: 0.9799 - val_loss: 0.7560 - val_accuracy: 0.8715
Epoch 47/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0610 - accuracy: 0.9794 - val_loss: 0.7559 - val_accuracy: 0.8693
Epoch 48/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0517 - accuracy: 0.9830 - val_loss: 0.7432 - val_accuracy: 0.8731
Epoch 49/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0561 - accuracy: 0.9812 - val_loss: 0.7700 - val_accuracy: 0.8678
Epoch 50/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0541 - accuracy: 0.9824 - val_loss: 0.7421 - val_accuracy: 0.8740
Epoch 51/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0600 - accuracy: 0.9793 - val_loss: 0.7385 - val_accuracy: 0.8751
Epoch 52/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0559 - accuracy: 0.9813 - val_loss: 0.7661 - val_accuracy: 0.8714
Epoch 53/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0583 - accuracy: 0.9809 - val_loss: 0.7691 - val_accuracy: 0.8712
Epoch 54/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0533 - accuracy: 0.9820 - val_loss: 0.7666 - val_accuracy: 0.8743
Epoch 55/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0514 - accuracy: 0.9839 - val_loss: 0.7781 - val_accuracy: 0.8733
Epoch 56/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0554 - accuracy: 0.9810 - val_loss: 0.7781 - val_accuracy: 0.8716
Epoch 57/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0586 - accuracy: 0.9802 - val_loss: 0.7568 - val_accuracy: 0.8723
Epoch 58/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0501 - accuracy: 0.9838 - val_loss: 0.7716 - val_accuracy: 0.8701
Epoch 59/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0508 - accuracy: 0.9830 - val_loss: 0.7655 - val_accuracy: 0.8717
Epoch 60/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0516 - accuracy: 0.9832 - val_loss: 0.7930 - val_accuracy: 0.8708
Epoch 61/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0561 - accuracy: 0.9812 - val_loss: 0.8031 - val_accuracy: 0.8700
Epoch 62/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0513 - accuracy: 0.9834 - val_loss: 0.7844 - val_accuracy: 0.8722
Epoch 63/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0524 - accuracy: 0.9826 - val_loss: 0.7902 - val_accuracy: 0.8696
Epoch 64/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0515 - accuracy: 0.9832 - val_loss: 0.8034 - val_accuracy: 0.8683
Epoch 65/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0476 - accuracy: 0.9847 - val_loss: 0.7984 - val_accuracy: 0.8702
Epoch 66/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0530 - accuracy: 0.9816 - val_loss: 0.8005 - val_accuracy: 0.8707
Epoch 67/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0511 - accuracy: 0.9834 - val_loss: 0.7899 - val_accuracy: 0.8696
Epoch 68/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0481 - accuracy: 0.9841 - val_loss: 0.7885 - val_accuracy: 0.8724
Epoch 69/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0501 - accuracy: 0.9829 - val_loss: 0.7863 - val_accuracy: 0.8721
Epoch 70/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0538 - accuracy: 0.9818 - val_loss: 0.8078 - val_accuracy: 0.8704
Epoch 71/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0540 - accuracy: 0.9810 - val_loss: 0.8011 - val_accuracy: 0.8684
Epoch 72/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0485 - accuracy: 0.9840 - val_loss: 0.7795 - val_accuracy: 0.8727
Epoch 73/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0494 - accuracy: 0.9834 - val_loss: 0.7984 - val_accuracy: 0.8745
Epoch 74/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0491 - accuracy: 0.9834 - val_loss: 0.7996 - val_accuracy: 0.8692
Epoch 75/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0511 - accuracy: 0.9830 - val_loss: 0.8042 - val_accuracy: 0.8709
Epoch 76/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0455 - accuracy: 0.9846 - val_loss: 0.8006 - val_accuracy: 0.8702
Epoch 77/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0504 - accuracy: 0.9831 - val_loss: 0.8045 - val_accuracy: 0.8692
Epoch 78/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0476 - accuracy: 0.9847 - val_loss: 0.8408 - val_accuracy: 0.8702
Epoch 79/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0504 - accuracy: 0.9840 - val_loss: 0.8045 - val_accuracy: 0.8681
Epoch 80/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0439 - accuracy: 0.9864 - val_loss: 0.8024 - val_accuracy: 0.8714
Epoch 81/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0463 - accuracy: 0.9848 - val_loss: 0.8147 - val_accuracy: 0.8698
Epoch 82/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0479 - accuracy: 0.9835 - val_loss: 0.8159 - val_accuracy: 0.8733
Epoch 83/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0469 - accuracy: 0.9843 - val_loss: 0.8203 - val_accuracy: 0.8714
Epoch 84/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0437 - accuracy: 0.9859 - val_loss: 0.8294 - val_accuracy: 0.8703
Epoch 85/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0485 - accuracy: 0.9836 - val_loss: 0.8578 - val_accuracy: 0.8677
Epoch 86/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0548 - accuracy: 0.9812 - val_loss: 0.8744 - val_accuracy: 0.8692
Epoch 87/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0428 - accuracy: 0.9870 - val_loss: 0.8249 - val_accuracy: 0.8727
Epoch 88/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0412 - accuracy: 0.9869 - val_loss: 0.8358 - val_accuracy: 0.8700
Epoch 89/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0501 - accuracy: 0.9822 - val_loss: 0.8284 - val_accuracy: 0.8723
Epoch 90/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0473 - accuracy: 0.9840 - val_loss: 0.8239 - val_accuracy: 0.8742
Epoch 91/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0446 - accuracy: 0.9855 - val_loss: 0.8341 - val_accuracy: 0.8702
Epoch 92/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0457 - accuracy: 0.9849 - val_loss: 0.8384 - val_accuracy: 0.8689
Epoch 93/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0452 - accuracy: 0.9847 - val_loss: 0.8330 - val_accuracy: 0.8747
Epoch 94/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0435 - accuracy: 0.9853 - val_loss: 0.8714 - val_accuracy: 0.8698
Epoch 95/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0428 - accuracy: 0.9860 - val_loss: 0.8581 - val_accuracy: 0.8686
Epoch 96/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0507 - accuracy: 0.9824 - val_loss: 0.8590 - val_accuracy: 0.8705
Epoch 97/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0413 - accuracy: 0.9861 - val_loss: 0.8483 - val_accuracy: 0.8703
Epoch 98/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0405 - accuracy: 0.9877 - val_loss: 0.8398 - val_accuracy: 0.8710
Epoch 99/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0407 - accuracy: 0.9872 - val_loss: 0.8464 - val_accuracy: 0.8703
Epoch 100/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0515 - accuracy: 0.9822 - val_loss: 0.8569 - val_accuracy: 0.8728
Epoch 101/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0413 - accuracy: 0.9870 - val_loss: 0.8622 - val_accuracy: 0.8685
Epoch 102/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0473 - accuracy: 0.9840 - val_loss: 0.8942 - val_accuracy: 0.8687
Epoch 103/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0493 - accuracy: 0.9839 - val_loss: 0.8599 - val_accuracy: 0.8717
Epoch 104/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0413 - accuracy: 0.9866 - val_loss: 0.8609 - val_accuracy: 0.8713
Epoch 105/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0409 - accuracy: 0.9864 - val_loss: 0.8830 - val_accuracy: 0.8699
Epoch 106/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0369 - accuracy: 0.9885 - val_loss: 0.8817 - val_accuracy: 0.8717
Epoch 107/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0432 - accuracy: 0.9852 - val_loss: 0.8812 - val_accuracy: 0.8675
Epoch 108/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0391 - accuracy: 0.9872 - val_loss: 0.8680 - val_accuracy: 0.8683
Epoch 109/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0406 - accuracy: 0.9868 - val_loss: 0.8937 - val_accuracy: 0.8645
Epoch 110/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0411 - accuracy: 0.9862 - val_loss: 0.8966 - val_accuracy: 0.8662
Epoch 111/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0492 - accuracy: 0.9832 - val_loss: 0.8811 - val_accuracy: 0.8742
Epoch 112/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0388 - accuracy: 0.9872 - val_loss: 0.8765 - val_accuracy: 0.8694
Epoch 113/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0451 - accuracy: 0.9848 - val_loss: 0.9364 - val_accuracy: 0.8708
Epoch 114/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0377 - accuracy: 0.9879 - val_loss: 0.8792 - val_accuracy: 0.8717
Epoch 115/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0387 - accuracy: 0.9877 - val_loss: 0.8825 - val_accuracy: 0.8697
Epoch 116/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0422 - accuracy: 0.9855 - val_loss: 0.8797 - val_accuracy: 0.8732
Epoch 117/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0384 - accuracy: 0.9878 - val_loss: 0.9020 - val_accuracy: 0.8708
Epoch 118/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0461 - accuracy: 0.9835 - val_loss: 0.9062 - val_accuracy: 0.8710
Epoch 119/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0373 - accuracy: 0.9885 - val_loss: 0.9100 - val_accuracy: 0.8683
Epoch 120/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0418 - accuracy: 0.9855 - val_loss: 0.8770 - val_accuracy: 0.8715
Epoch 121/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0420 - accuracy: 0.9857 - val_loss: 0.9350 - val_accuracy: 0.8680
Epoch 122/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0418 - accuracy: 0.9864 - val_loss: 0.9297 - val_accuracy: 0.8658
Epoch 123/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0382 - accuracy: 0.9874 - val_loss: 0.8977 - val_accuracy: 0.8729
Epoch 124/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0420 - accuracy: 0.9864 - val_loss: 0.9124 - val_accuracy: 0.8716
Epoch 125/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0354 - accuracy: 0.9887 - val_loss: 0.9085 - val_accuracy: 0.8688
Epoch 126/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0403 - accuracy: 0.9865 - val_loss: 0.9202 - val_accuracy: 0.8703
Epoch 127/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0400 - accuracy: 0.9869 - val_loss: 0.9095 - val_accuracy: 0.8708
Epoch 128/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0368 - accuracy: 0.9880 - val_loss: 0.9127 - val_accuracy: 0.8705
Epoch 129/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0412 - accuracy: 0.9871 - val_loss: 0.9065 - val_accuracy: 0.8713
Epoch 130/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0333 - accuracy: 0.9891 - val_loss: 0.9083 - val_accuracy: 0.8712
Epoch 131/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0372 - accuracy: 0.9878 - val_loss: 0.9444 - val_accuracy: 0.8638
Epoch 132/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0418 - accuracy: 0.9862 - val_loss: 0.9335 - val_accuracy: 0.8691
Epoch 133/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0418 - accuracy: 0.9861 - val_loss: 0.9234 - val_accuracy: 0.8698
Epoch 134/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0333 - accuracy: 0.9891 - val_loss: 0.9453 - val_accuracy: 0.8671
Epoch 135/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0337 - accuracy: 0.9889 - val_loss: 0.9316 - val_accuracy: 0.8709
Epoch 136/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0351 - accuracy: 0.9882 - val_loss: 0.9238 - val_accuracy: 0.8704
Epoch 137/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0339 - accuracy: 0.9887 - val_loss: 0.9206 - val_accuracy: 0.8712
Epoch 138/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0368 - accuracy: 0.9877 - val_loss: 0.9531 - val_accuracy: 0.8687
Epoch 139/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0321 - accuracy: 0.9904 - val_loss: 0.9311 - val_accuracy: 0.8711
Epoch 140/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0414 - accuracy: 0.9862 - val_loss: 0.9664 - val_accuracy: 0.8684
Epoch 141/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0370 - accuracy: 0.9873 - val_loss: 0.9412 - val_accuracy: 0.8698
Epoch 142/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0332 - accuracy: 0.9897 - val_loss: 0.9607 - val_accuracy: 0.8675
Epoch 143/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0353 - accuracy: 0.9883 - val_loss: 0.9616 - val_accuracy: 0.8663
Epoch 144/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0347 - accuracy: 0.9886 - val_loss: 0.9633 - val_accuracy: 0.8692
Epoch 145/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0335 - accuracy: 0.9898 - val_loss: 0.9780 - val_accuracy: 0.8673
Epoch 146/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0336 - accuracy: 0.9895 - val_loss: 0.9465 - val_accuracy: 0.8708
Epoch 147/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0401 - accuracy: 0.9869 - val_loss: 0.9635 - val_accuracy: 0.8697
Epoch 148/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0361 - accuracy: 0.9881 - val_loss: 0.9839 - val_accuracy: 0.8679
Epoch 149/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0412 - accuracy: 0.9860 - val_loss: 0.9606 - val_accuracy: 0.8725
Epoch 150/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0312 - accuracy: 0.9904 - val_loss: 0.9511 - val_accuracy: 0.8709
Epoch 151/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0317 - accuracy: 0.9897 - val_loss: 0.9668 - val_accuracy: 0.8712
Epoch 152/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0338 - accuracy: 0.9895 - val_loss: 0.9609 - val_accuracy: 0.8711
Epoch 153/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0383 - accuracy: 0.9872 - val_loss: 0.9816 - val_accuracy: 0.8692
Epoch 154/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0301 - accuracy: 0.9911 - val_loss: 0.9526 - val_accuracy: 0.8686
Epoch 155/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0323 - accuracy: 0.9892 - val_loss: 0.9598 - val_accuracy: 0.8683
Epoch 156/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0317 - accuracy: 0.9897 - val_loss: 0.9968 - val_accuracy: 0.8676
Epoch 157/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0303 - accuracy: 0.9906 - val_loss: 0.9830 - val_accuracy: 0.8682
Epoch 158/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0410 - accuracy: 0.9860 - val_loss: 1.0750 - val_accuracy: 0.8634
Epoch 159/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0384 - accuracy: 0.9878 - val_loss: 1.0036 - val_accuracy: 0.8661
Epoch 160/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0346 - accuracy: 0.9886 - val_loss: 0.9764 - val_accuracy: 0.8706
Epoch 161/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0330 - accuracy: 0.9891 - val_loss: 0.9940 - val_accuracy: 0.8723
Epoch 162/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0281 - accuracy: 0.9918 - val_loss: 0.9813 - val_accuracy: 0.8719
Epoch 163/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0283 - accuracy: 0.9911 - val_loss: 1.0107 - val_accuracy: 0.8686
Epoch 164/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0392 - accuracy: 0.9866 - val_loss: 0.9868 - val_accuracy: 0.8695
Epoch 165/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0284 - accuracy: 0.9914 - val_loss: 0.9845 - val_accuracy: 0.8702
Epoch 166/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0308 - accuracy: 0.9898 - val_loss: 1.0053 - val_accuracy: 0.8699
Epoch 167/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0295 - accuracy: 0.9903 - val_loss: 0.9996 - val_accuracy: 0.8698
Epoch 168/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0309 - accuracy: 0.9897 - val_loss: 1.0013 - val_accuracy: 0.8693
Epoch 169/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0348 - accuracy: 0.9886 - val_loss: 1.0201 - val_accuracy: 0.8699
Epoch 170/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0336 - accuracy: 0.9891 - val_loss: 1.0624 - val_accuracy: 0.8623
Epoch 171/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0400 - accuracy: 0.9856 - val_loss: 1.0075 - val_accuracy: 0.8714
Epoch 172/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0283 - accuracy: 0.9911 - val_loss: 1.0117 - val_accuracy: 0.8694
Epoch 173/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0321 - accuracy: 0.9890 - val_loss: 0.9917 - val_accuracy: 0.8706
Epoch 174/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0273 - accuracy: 0.9911 - val_loss: 1.0176 - val_accuracy: 0.8684
Epoch 175/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0375 - accuracy: 0.9875 - val_loss: 1.0277 - val_accuracy: 0.8682
Epoch 176/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0274 - accuracy: 0.9912 - val_loss: 1.0145 - val_accuracy: 0.8714
Epoch 177/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0300 - accuracy: 0.9906 - val_loss: 1.0152 - val_accuracy: 0.8686
Epoch 178/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0247 - accuracy: 0.9926 - val_loss: 1.0244 - val_accuracy: 0.8700
Epoch 179/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0290 - accuracy: 0.9908 - val_loss: 1.0125 - val_accuracy: 0.8719
Epoch 180/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0280 - accuracy: 0.9912 - val_loss: 1.0212 - val_accuracy: 0.8699
Epoch 181/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0306 - accuracy: 0.9900 - val_loss: 1.0240 - val_accuracy: 0.8652
Epoch 182/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0309 - accuracy: 0.9902 - val_loss: 1.0208 - val_accuracy: 0.8716
Epoch 183/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0334 - accuracy: 0.9889 - val_loss: 1.0276 - val_accuracy: 0.8687
Epoch 184/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0292 - accuracy: 0.9901 - val_loss: 1.0357 - val_accuracy: 0.8684
Epoch 185/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0298 - accuracy: 0.9904 - val_loss: 1.0384 - val_accuracy: 0.8696
Epoch 186/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0286 - accuracy: 0.9909 - val_loss: 1.0388 - val_accuracy: 0.8671
Epoch 187/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0292 - accuracy: 0.9903 - val_loss: 1.0247 - val_accuracy: 0.8682
Epoch 188/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0300 - accuracy: 0.9904 - val_loss: 1.0421 - val_accuracy: 0.8683
Epoch 189/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0384 - accuracy: 0.9864 - val_loss: 1.0659 - val_accuracy: 0.8677
Epoch 190/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0277 - accuracy: 0.9911 - val_loss: 1.0429 - val_accuracy: 0.8712
Epoch 191/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0296 - accuracy: 0.9907 - val_loss: 1.0657 - val_accuracy: 0.8702
Epoch 192/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0295 - accuracy: 0.9902 - val_loss: 1.0342 - val_accuracy: 0.8695
Epoch 193/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0216 - accuracy: 0.9936 - val_loss: 1.0715 - val_accuracy: 0.8693
Epoch 194/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0304 - accuracy: 0.9900 - val_loss: 1.0507 - val_accuracy: 0.8662
Epoch 195/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0319 - accuracy: 0.9894 - val_loss: 1.0426 - val_accuracy: 0.8732
Epoch 196/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0286 - accuracy: 0.9905 - val_loss: 1.0477 - val_accuracy: 0.8704
Epoch 197/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0289 - accuracy: 0.9908 - val_loss: 1.0816 - val_accuracy: 0.8705
Epoch 198/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0377 - accuracy: 0.9872 - val_loss: 1.0396 - val_accuracy: 0.8680
Epoch 199/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0234 - accuracy: 0.9930 - val_loss: 1.0712 - val_accuracy: 0.8654
Epoch 200/200
240/240 [==============================] - 1s 4ms/step - loss: 0.0256 - accuracy: 0.9919 - val_loss: 1.0607 - val_accuracy: 0.8704
<keras.callbacks.History at 0x7fdaf86957e0>

callback 넣었을 때랑 넣지 않았을때랑 시작하는 accuracy가 달랐다.

이미지니까 loss function tf.losses.categorical_crossentropy

,validation_split=0.2 20%만큼 validattion 을 val set 으로 뺴내겠다.

한 20 전에는 끊어도 상관없어, 그 이후에는 accuracy 변화가 거의 없다고 해도 무방하니까!

- 텐서보드 여는 방법1

%load_ext tensorboard
# 주피터노트북 (혹은 주피터랩)에서 텐서보드를 임베딩하여 넣을 수 있도록 도와주는 매직펑션
#!kill 313799

주피터랩의 서버로 늘어가는 경우는 IP주소같은 형식의 무엇인가가 필요한가봐

training accuracy는 올라가는데 validation accuracy는 그저 그렇다(우리의 목적이 아님)

training loss는 줄어들고 있는데 validation loss는 오히려 커지고 있다.(이상함을 감지)

-> 오버피팅의 징조!!!

%tensorboard --logdir logs --host 0.0.0.0
# %tensorboard --logdir logs <-- 실습에서는 이렇게 하면됩니다. 

(참고사항) 파이썬 3.10의 경우 아래의 수정이 필요

?/python3.10/site-packages/tensorboard/_vendor/html5lib/_trie/_base.py 을 열고

from collections import Mapping ### 수정전
from collections.abc import Mapping ### 수정후

와 같이 수정한다.

  • 왜냐하면 파이썬 3.10부터 from collections import Mapping 가 동작하지 않고 from collections.abc import Mapping 가 동작하도록 문법이 바뀜

- 텐서보드를 실행하는 방법2

!tensorboard --logdir logs --host 0.0.0.0
#!tensorboard --logdir logs
#<-- 실습에서는 이렇게 하면됩니다. 
NOTE: Using experimental fast data loading logic. To disable, pass
    "--load_fast=false" and report issues on GitHub. More details:
    https://github.com/tensorflow/tensorboard/issues/4784

TensorBoard 2.6.0 at http://0.0.0.0:6007/ (Press CTRL+C to quit)
^C

조기종료

- 텐서보드를 살펴보니 특정에폭 이후에는 오히려 과적합이 진행되는 듯 하다 (학습할수록 손해인듯 하다) $\to$ 그 특정에폭까지만 학습해보자

tf.random.set_seed(43052)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Flatten())
net.add(tf.keras.layers.Dense(5000,activation='relu')) ## 과적합좀 시키려고 
net.add(tf.keras.layers.Dense(5000,activation='relu')) ## 레이어를 2장만듦 + 레이어하나당 노드수도 증가 
net.add(tf.keras.layers.Dense(10,activation='softmax'))
net.compile(optimizer='adam',loss=tf.losses.categorical_crossentropy,metrics='accuracy')

val-loss 가 한 번 올라간다? 즉, 그래프가 상승해서 멈춘다! 는 뜻! 오목한 부분이 끝날때마다!

#cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=1) # val-loss가 1회 증가하면 멈추어라 
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=cb2,verbose=1) 
Epoch 1/200
240/240 [==============================] - 2s 6ms/step - loss: 0.5493 - accuracy: 0.8127 - val_loss: 0.4113 - val_accuracy: 0.8497
Epoch 2/200
240/240 [==============================] - 1s 6ms/step - loss: 0.3571 - accuracy: 0.8673 - val_loss: 0.3793 - val_accuracy: 0.8649
Epoch 3/200
240/240 [==============================] - 1s 6ms/step - loss: 0.3254 - accuracy: 0.8791 - val_loss: 0.3679 - val_accuracy: 0.8677
Epoch 4/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2978 - accuracy: 0.8869 - val_loss: 0.3498 - val_accuracy: 0.8791
Epoch 5/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2794 - accuracy: 0.8960 - val_loss: 0.3341 - val_accuracy: 0.8791
Epoch 6/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2618 - accuracy: 0.9001 - val_loss: 0.3264 - val_accuracy: 0.8827
Epoch 7/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2472 - accuracy: 0.9066 - val_loss: 0.3363 - val_accuracy: 0.8802
<keras.callbacks.History at 0x7f54031d1540>
#cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=1) # val-loss가 1회증가하면 멈추어라 
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=cb2,verbose=1) 
Epoch 1/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2388 - accuracy: 0.9080 - val_loss: 0.3112 - val_accuracy: 0.8863
Epoch 2/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2245 - accuracy: 0.9143 - val_loss: 0.3266 - val_accuracy: 0.8887
<keras.callbacks.History at 0x7f5403070fd0>
#cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=1) # val-loss가 1회증가하면 멈추어라 
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=cb2,verbose=1) 
Epoch 1/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2164 - accuracy: 0.9161 - val_loss: 0.3316 - val_accuracy: 0.8876
Epoch 2/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2010 - accuracy: 0.9223 - val_loss: 0.3334 - val_accuracy: 0.8884
<keras.callbacks.History at 0x7f54030de320>
#cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=1) # val-loss가 1회증가하면 멈추어라 
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=cb2,verbose=1) 
Epoch 1/200
240/240 [==============================] - 1s 6ms/step - loss: 0.1909 - accuracy: 0.9257 - val_loss: 0.3789 - val_accuracy: 0.8819
Epoch 2/200
240/240 [==============================] - 1s 6ms/step - loss: 0.1864 - accuracy: 0.9275 - val_loss: 0.3458 - val_accuracy: 0.8890
Epoch 3/200
240/240 [==============================] - 1s 6ms/step - loss: 0.1852 - accuracy: 0.9290 - val_loss: 0.3508 - val_accuracy: 0.8903
<keras.callbacks.History at 0x7f5403116d10>
#cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=1) # val-loss가 1회증가하면 멈추어라 
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=cb2,verbose=1) 
Epoch 1/200
240/240 [==============================] - 2s 6ms/step - loss: 0.1653 - accuracy: 0.9339 - val_loss: 0.3870 - val_accuracy: 0.8848
Epoch 2/200
240/240 [==============================] - 1s 6ms/step - loss: 0.1574 - accuracy: 0.9383 - val_loss: 0.3708 - val_accuracy: 0.8921
Epoch 3/200
240/240 [==============================] - 1s 6ms/step - loss: 0.1558 - accuracy: 0.9390 - val_loss: 0.3727 - val_accuracy: 0.8890
<keras.callbacks.History at 0x7f5403147bb0>

- 몇 번 좀 참았다가 멈추면 좋겠다.

tf.random.set_seed(43052)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Flatten())
net.add(tf.keras.layers.Dense(5000,activation='relu')) ## 과적합좀 시키려고 
net.add(tf.keras.layers.Dense(5000,activation='relu')) ## 레이어를 2장만듬 + 레이어하나당 노드수도 증가 
net.add(tf.keras.layers.Dense(10,activation='softmax'))
net.compile(optimizer='adam',loss=tf.losses.categorical_crossentropy,metrics='accuracy')
#cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=5) # 좀더 참다가 멈추어라 
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=cb2,verbose=1) 
Epoch 1/200
240/240 [==============================] - 2s 6ms/step - loss: 0.5489 - accuracy: 0.8131 - val_loss: 0.4094 - val_accuracy: 0.8514
Epoch 2/200
240/240 [==============================] - 1s 6ms/step - loss: 0.3556 - accuracy: 0.8681 - val_loss: 0.3624 - val_accuracy: 0.8708
Epoch 3/200
240/240 [==============================] - 1s 6ms/step - loss: 0.3206 - accuracy: 0.8796 - val_loss: 0.3538 - val_accuracy: 0.8715
Epoch 4/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2952 - accuracy: 0.8889 - val_loss: 0.3466 - val_accuracy: 0.8776
Epoch 5/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2775 - accuracy: 0.8963 - val_loss: 0.3236 - val_accuracy: 0.8822
Epoch 6/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2600 - accuracy: 0.9015 - val_loss: 0.3257 - val_accuracy: 0.8818
Epoch 7/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2449 - accuracy: 0.9080 - val_loss: 0.3098 - val_accuracy: 0.8875
Epoch 8/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2315 - accuracy: 0.9110 - val_loss: 0.3289 - val_accuracy: 0.8860
Epoch 9/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2230 - accuracy: 0.9161 - val_loss: 0.3139 - val_accuracy: 0.8903
Epoch 10/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2101 - accuracy: 0.9188 - val_loss: 0.3216 - val_accuracy: 0.8887
Epoch 11/200
240/240 [==============================] - 1s 6ms/step - loss: 0.2087 - accuracy: 0.9197 - val_loss: 0.3342 - val_accuracy: 0.8827
Epoch 12/200
240/240 [==============================] - 1s 6ms/step - loss: 0.1988 - accuracy: 0.9235 - val_loss: 0.3245 - val_accuracy: 0.8942
<keras.callbacks.History at 0x7f51fc5e1d50>

- 텐서보드로 그려보자?

텐서보드 기능이 없는 상태

%tensorboard --logdir logs --host 0.0.0.0 
# 아무것도 안나온다 -> 왜? cb1을 써야 텐서보드가 나옴

조기종료cb2와 텐서플로우show cb1을 함께 써서 안 보이는 문제가 생겨버렸다.

- 조기종료와 텐서보드를 같이 쓰려면?

 
tf.random.set_seed(43052)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Flatten())
net.add(tf.keras.layers.Dense(50,activation='relu')) 
net.add(tf.keras.layers.Dense(10,activation='softmax'))
net.compile(optimizer='adam',loss=tf.losses.categorical_crossentropy,metrics='accuracy')
cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=7) # 좀더 참다가 멈추어라 
net.fit(X,y,epochs=200,batch_size=200,validation_split=0.2,callbacks=[cb1,cb2]) 
Epoch 1/200
240/240 [==============================] - 1s 5ms/step - loss: 0.7184 - accuracy: 0.7581 - val_loss: 0.5077 - val_accuracy: 0.8276
Epoch 2/200
240/240 [==============================] - 1s 4ms/step - loss: 0.4752 - accuracy: 0.8386 - val_loss: 0.4793 - val_accuracy: 0.8342
Epoch 3/200
240/240 [==============================] - 1s 4ms/step - loss: 0.4304 - accuracy: 0.8517 - val_loss: 0.4386 - val_accuracy: 0.8497
Epoch 4/200
240/240 [==============================] - 1s 4ms/step - loss: 0.4048 - accuracy: 0.8582 - val_loss: 0.4029 - val_accuracy: 0.8603
Epoch 5/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3832 - accuracy: 0.8669 - val_loss: 0.3932 - val_accuracy: 0.8619
Epoch 6/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3697 - accuracy: 0.8705 - val_loss: 0.3842 - val_accuracy: 0.8657
Epoch 7/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3569 - accuracy: 0.8759 - val_loss: 0.3844 - val_accuracy: 0.8668
Epoch 8/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3482 - accuracy: 0.8774 - val_loss: 0.3679 - val_accuracy: 0.8708
Epoch 9/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3387 - accuracy: 0.8799 - val_loss: 0.3602 - val_accuracy: 0.8719
Epoch 10/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3299 - accuracy: 0.8820 - val_loss: 0.3610 - val_accuracy: 0.8748
Epoch 11/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3229 - accuracy: 0.8858 - val_loss: 0.3574 - val_accuracy: 0.8717
Epoch 12/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3157 - accuracy: 0.8873 - val_loss: 0.3572 - val_accuracy: 0.8743
Epoch 13/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3106 - accuracy: 0.8899 - val_loss: 0.3545 - val_accuracy: 0.8761
Epoch 14/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3046 - accuracy: 0.8914 - val_loss: 0.3493 - val_accuracy: 0.8759
Epoch 15/200
240/240 [==============================] - 1s 4ms/step - loss: 0.3011 - accuracy: 0.8928 - val_loss: 0.3483 - val_accuracy: 0.8776
Epoch 16/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2988 - accuracy: 0.8935 - val_loss: 0.3733 - val_accuracy: 0.8716
Epoch 17/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2925 - accuracy: 0.8947 - val_loss: 0.3481 - val_accuracy: 0.8768
Epoch 18/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2880 - accuracy: 0.8951 - val_loss: 0.3396 - val_accuracy: 0.8801
Epoch 19/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2827 - accuracy: 0.8982 - val_loss: 0.3439 - val_accuracy: 0.8798
Epoch 20/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2791 - accuracy: 0.8986 - val_loss: 0.3489 - val_accuracy: 0.8779
Epoch 21/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2765 - accuracy: 0.9007 - val_loss: 0.3350 - val_accuracy: 0.8823
Epoch 22/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2709 - accuracy: 0.9016 - val_loss: 0.3350 - val_accuracy: 0.8812
Epoch 23/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2688 - accuracy: 0.9029 - val_loss: 0.3374 - val_accuracy: 0.8820
Epoch 24/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2658 - accuracy: 0.9041 - val_loss: 0.3445 - val_accuracy: 0.8805
Epoch 25/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2607 - accuracy: 0.9058 - val_loss: 0.3383 - val_accuracy: 0.8822
Epoch 26/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2607 - accuracy: 0.9056 - val_loss: 0.3415 - val_accuracy: 0.8811
Epoch 27/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2576 - accuracy: 0.9068 - val_loss: 0.3402 - val_accuracy: 0.8814
Epoch 28/200
240/240 [==============================] - 1s 4ms/step - loss: 0.2525 - accuracy: 0.9098 - val_loss: 0.3469 - val_accuracy: 0.8802
<keras.callbacks.History at 0x7f51fc47c0a0>

결과 해석

  • training accuracy가 validation accuracy보다 높다?
  • training loss가 validation loss보다 낮다?
# 조기종료가 구현된 그림이 출력
%tensorboard --logdir logs --host 0.0.0.0 
Reusing TensorBoard on port 6006 (pid 702426), started 0:01:48 ago. (Use '!kill 702426' to kill it.)

하이퍼파라메터 선택

- 하이퍼파라메터 설정

여러 상황에서 반복 실험시 유용

from tensorboard.plugins.hparams import api as hp
a=net.evaluate(XX,yy)
313/313 [==============================] - 1s 3ms/step - loss: 0.3817 - accuracy: 0.8706
type(a)
list
a
[0.3817201852798462, 0.8705999851226807]

_rslt=net.evaluate(XX,yy)

  • test의 해당되는 evaluate

_mymetric=_rslt[1]*0.8 + _rslt[2]*0.2

  • 내가 보고 싶은 것은 recall
  • test의 accuracy 가 rsit[1]에 있어
  • test의 recall이 rsit[2]
  • 가중 평균을 보겠다, 이건 정해진거는 아니고 마음대로..

with문이 있다는 건 들어갈때 나갈때가 정의되어 있다는 거

!rm -rf logs
for u in [50,5000]: 
    for d in [0.0,0.5]: 
        for o in ['adam','sgd']:
            logdir = 'logs/hpguebin_{}_{}_{}'.format(u,d,o)
            with tf.summary.create_file_writer(logdir).as_default():
                net = tf.keras.Sequential()
                net.add(tf.keras.layers.Flatten())
                net.add(tf.keras.layers.Dense(u,activation='relu'))
                net.add(tf.keras.layers.Dropout(d))
                net.add(tf.keras.layers.Dense(10,activation='softmax'))
                net.compile(optimizer=o,loss=tf.losses.categorical_crossentropy,metrics=['accuracy','Recall'])
                cb3 = hp.KerasCallback(logdir, {'유닛수':u, '드랍아웃비율':d, '옵티마이저':o})
                net.fit(X,y,epochs=3,callbacks=cb3)
                _rslt=net.evaluate(XX,yy)
                _mymetric=_rslt[1]*0.8 + _rslt[2]*0.2  
                tf.summary.scalar('애큐러시와리컬의가중평균(테스트셋)', _mymetric, step=1) 
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.5364 - accuracy: 0.8143 - recall: 0.7509
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4072 - accuracy: 0.8559 - recall: 0.8242
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3725 - accuracy: 0.8668 - recall: 0.8413
313/313 [==============================] - 1s 4ms/step - loss: 0.4010 - accuracy: 0.8572 - recall: 0.8301
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.7590 - accuracy: 0.7494 - recall: 0.5859
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.5225 - accuracy: 0.8223 - recall: 0.7521
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4754 - accuracy: 0.8356 - recall: 0.7833
313/313 [==============================] - 1s 3ms/step - loss: 0.4910 - accuracy: 0.8274 - recall: 0.7813
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.7480 - accuracy: 0.7374 - recall: 0.6156
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.5666 - accuracy: 0.7983 - recall: 0.7225
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.5325 - accuracy: 0.8080 - recall: 0.7416
313/313 [==============================] - 1s 4ms/step - loss: 0.4301 - accuracy: 0.8487 - recall: 0.7878
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 1.0498 - accuracy: 0.6383 - recall: 0.4178
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.7483 - accuracy: 0.7434 - recall: 0.6015
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.6737 - accuracy: 0.7699 - recall: 0.6519
313/313 [==============================] - 1s 4ms/step - loss: 0.5269 - accuracy: 0.8169 - recall: 0.7380
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4760 - accuracy: 0.8278 - recall: 0.7880
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3607 - accuracy: 0.8683 - recall: 0.8424
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3239 - accuracy: 0.8817 - recall: 0.8591
313/313 [==============================] - 1s 4ms/step - loss: 0.3508 - accuracy: 0.8737 - recall: 0.8516
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.6701 - accuracy: 0.7875 - recall: 0.6453
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4827 - accuracy: 0.8362 - recall: 0.7766
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4422 - accuracy: 0.8481 - recall: 0.8006
313/313 [==============================] - 1s 4ms/step - loss: 0.4625 - accuracy: 0.8398 - recall: 0.7971
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.5722 - accuracy: 0.7997 - recall: 0.7570
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4404 - accuracy: 0.8398 - recall: 0.8067
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4103 - accuracy: 0.8504 - recall: 0.8204
313/313 [==============================] - 1s 4ms/step - loss: 0.3789 - accuracy: 0.8662 - recall: 0.8362
Epoch 1/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.6961 - accuracy: 0.7745 - recall: 0.6357
Epoch 2/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.5041 - accuracy: 0.8285 - recall: 0.7665
Epoch 3/3
1875/1875 [==============================] - 8s 4ms/step - loss: 0.4606 - accuracy: 0.8415 - recall: 0.7904
313/313 [==============================] - 1s 4ms/step - loss: 0.4603 - accuracy: 0.8402 - recall: 0.7931

opt가 adma일 때보다 sgd 일때

%tensorboard --logdir logs --host 0.0.0.0
Reusing TensorBoard on port 6006 (pid 704607), started 0:02:40 ago. (Use '!kill 704607' to kill it.)

숙제

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
X= x_train.reshape(-1,28,28,1)/255 ## 입력이 0~255 -> 0~1로 표준화 시키는 효과 + float으로 자료형이 바뀜 
y = tf.keras.utils.to_categorical(y_train)
XX = x_test.reshape(-1,28,28,1)/255
yy = tf.keras.utils.to_categorical(y_test)

- 아래의 네트워크에서 옵티마이저를 adam, sgd를 선택하여 각각 적합시켜보고 testset의 loss를 성능비교를 하라. epoch은 5정도로 설정하라.

net = tf.keras.Sequential()
net.add(tf.keras.layers.Flatten())
net.add(tf.keras.layers.Dense(50,activation='relu'))
net.add(tf.keras.layers.Dense(50,activation='relu'))
net.add(tf.keras.layers.Dense(10,activation='softmax'))
net.compile(optimizer=???,loss=tf.losses.categorical_crossentropy,metrics=['accuracy','Recall'])

- adam 적합

!rm -rf logs
tf.random.set_seed(202150754)
net1 = tf.keras.Sequential()
net1.add(tf.keras.layers.Flatten())
net1.add(tf.keras.layers.Dense(50,activation='relu'))
net1.add(tf.keras.layers.Dense(50,activation='relu'))
net1.add(tf.keras.layers.Dense(10,activation='softmax'))
net1.compile(optimizer='adam',loss=tf.losses.categorical_crossentropy,metrics=['accuracy','Recall'])
cb1 = tf.keras.callbacks.TensorBoard()
cb2 = tf.keras.callbacks.EarlyStopping(patience=7) 
net1.fit(X,y,epochs=5,batch_size=200,validation_split=0.2,callbacks=[cb1,cb2]) 
Epoch 1/5
240/240 [==============================] - 2s 6ms/step - loss: 0.7224 - accuracy: 0.7586 - recall: 0.6304 - val_loss: 0.4817 - val_accuracy: 0.8329 - val_recall: 0.7788
Epoch 2/5
240/240 [==============================] - 1s 5ms/step - loss: 0.4508 - accuracy: 0.8419 - recall: 0.7951 - val_loss: 0.4497 - val_accuracy: 0.8349 - val_recall: 0.7932
Epoch 3/5
240/240 [==============================] - 1s 5ms/step - loss: 0.4064 - accuracy: 0.8567 - recall: 0.8202 - val_loss: 0.4013 - val_accuracy: 0.8540 - val_recall: 0.8188
Epoch 4/5
240/240 [==============================] - 1s 5ms/step - loss: 0.3728 - accuracy: 0.8685 - recall: 0.8364 - val_loss: 0.3892 - val_accuracy: 0.8611 - val_recall: 0.8289
Epoch 5/5
240/240 [==============================] - 1s 5ms/step - loss: 0.3571 - accuracy: 0.8714 - recall: 0.8434 - val_loss: 0.3857 - val_accuracy: 0.8620 - val_recall: 0.8403
<keras.callbacks.History at 0x7f3848153fd0>

- adam tensorboard

%tensorboard --logdir logs --host 0.0.0.0
Reusing TensorBoard on port 6006 (pid 1366833), started 0:01:06 ago. (Use '!kill 1366833' to kill it.)

- sgd 적합

!rm -rf logs
tf.random.set_seed(202150754)
net2 = tf.keras.Sequential()
net2.add(tf.keras.layers.Flatten())
net2.add(tf.keras.layers.Dense(50,activation='relu'))
net2.add(tf.keras.layers.Dense(50,activation='relu'))
net2.add(tf.keras.layers.Dense(10,activation='softmax'))
net2.compile(optimizer='sgd',loss=tf.losses.categorical_crossentropy,metrics=['accuracy','Recall'])
net2.fit(X,y,epochs=5,batch_size=200,validation_split=0.2,callbacks=[cb1,cb2]) 
Epoch 1/5
240/240 [==============================] - 2s 5ms/step - loss: 1.6588 - accuracy: 0.4999 - recall: 0.0831 - val_loss: 1.1223 - val_accuracy: 0.6730 - val_recall: 0.2842
Epoch 2/5
240/240 [==============================] - 1s 5ms/step - loss: 0.9301 - accuracy: 0.6911 - recall: 0.4377 - val_loss: 0.8035 - val_accuracy: 0.7196 - val_recall: 0.5241
Epoch 3/5
240/240 [==============================] - 1s 5ms/step - loss: 0.7534 - accuracy: 0.7372 - recall: 0.5661 - val_loss: 0.7023 - val_accuracy: 0.7613 - val_recall: 0.6117
Epoch 4/5
240/240 [==============================] - 1s 5ms/step - loss: 0.6757 - accuracy: 0.7693 - recall: 0.6336 - val_loss: 0.6443 - val_accuracy: 0.7802 - val_recall: 0.6617
Epoch 5/5
240/240 [==============================] - 1s 5ms/step - loss: 0.6253 - accuracy: 0.7891 - recall: 0.6790 - val_loss: 0.6030 - val_accuracy: 0.7968 - val_recall: 0.6976
<keras.callbacks.History at 0x7f8ca85c3370>

- sgd tensorboard

%tensorboard --logdir logs --host 0.0.0.0
Reusing TensorBoard on port 6006 (pid 847006), started 0:00:02 ago. (Use '!kill 847006' to kill it.)
net1.evaluate(XX,yy)[0]
313/313 [==============================] - 1s 4ms/step - loss: 0.4171 - accuracy: 0.8543 - recall: 0.8275
0.41707098484039307
net2.evaluate(XX,yy)[0]
313/313 [==============================] - 1s 4ms/step - loss: 0.6277 - accuracy: 0.7835 - recall: 0.6898
0.6277241706848145

adam을 optimizer로 선택하였을때 loss는 0.41707104444503784이었으며,

sgd를 optimizer로 선택하였을때 loss는 0.6277242302894592이었다.

loss값만 보았을때는 adamsgd보다 낮았다.

adam은 trianing loss와 validation loss가 같은 수준까지 낮아지는 모습이지만,

sgd는 training loss보다 validation loss가 더 낮은 수준까지 loss가 떨어졌다.

opptimizer로 sgd를 적합시켰을때, 20%의 validation을 제외한 training data로 학습을 한 것보다 20%의 validation의 loss가 더 낮았다는 원하는 결과가 도출되었다.