import tensorflow as tf
import tensorflow.experimental.numpy as tnp
import numpy as np
import matplotlib.pyplot as plt
해당 강의노트는 전북대학교 최규빈교수님 STBDA2022 자료임
imports
tnp.experimental_enable_numpy_behavior()
= tf.keras.datasets.fashion_mnist.load_data() (x_train, y_train), (x_test, y_test)
= tf.constant(x_train.reshape(-1,28,28,1),dtype=tf.float64)
X = tf.keras.utils.to_categorical(y_train)
y = tf.constant(x_test.reshape(-1,28,28,1),dtype=tf.float64)
XX = tf.keras.utils.to_categorical(y_test) yy
-
첫시도
= tf.keras.Sequential()
net1
net1.add(tf.keras.layers.Flatten())500,activation='relu'))
net1.add(tf.keras.layers.Dense(500,activation='relu'))
net1.add(tf.keras.layers.Dense(500,activation='relu'))
net1.add(tf.keras.layers.Dense(500,activation='relu'))
net1.add(tf.keras.layers.Dense(10,activation='softmax'))
net1.add(tf.keras.layers.Dense(compile(optimizer='adam', loss=tf.losses.categorical_crossentropy,metrics='accuracy')
net1.=5) net1.fit(X,y,epochs
Epoch 1/5
1875/1875 [==============================] - 5s 3ms/step - loss: 1.0329 - accuracy: 0.7892
Epoch 2/5
1875/1875 [==============================] - 5s 2ms/step - loss: 0.4472 - accuracy: 0.8415
Epoch 3/5
1875/1875 [==============================] - 5s 2ms/step - loss: 0.4179 - accuracy: 0.8497
Epoch 4/5
1875/1875 [==============================] - 5s 2ms/step - loss: 0.3942 - accuracy: 0.8598
Epoch 5/5
1875/1875 [==============================] - 5s 2ms/step - loss: 0.3756 - accuracy: 0.8668
<keras.callbacks.History at 0x7f07e021dfa0>
net1.evaluate(XX,yy)
313/313 [==============================] - 0s 754us/step - loss: 0.4255 - accuracy: 0.8505
[0.4255034327507019, 0.8504999876022339]
net1.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten (Flatten) (None, 784) 0
dense (Dense) (None, 500) 392500
dense_1 (Dense) (None, 500) 250500
dense_2 (Dense) (None, 500) 250500
dense_3 (Dense) (None, 500) 250500
dense_4 (Dense) (None, 10) 5010
=================================================================
Total params: 1,149,010
Trainable params: 1,149,010
Non-trainable params: 0
_________________________________________________________________
-
두번째 시도
= tf.keras.Sequential()
net2 30,(2,2),activation='relu'))
net2.add(tf.keras.layers.Conv2D(
net2.add(tf.keras.layers.MaxPool2D())30,(2,2),activation='relu'))
net2.add(tf.keras.layers.Conv2D(
net2.add(tf.keras.layers.MaxPool2D())
net2.add(tf.keras.layers.Flatten())#net2.add(tf.keras.layers.Dense(500,activation='relu'))
10,activation='softmax'))
net2.add(tf.keras.layers.Dense(compile(optimizer='adam', loss=tf.losses.categorical_crossentropy,metrics='accuracy')
net2.=5) net2.fit(X,y,epochs
Epoch 1/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.7960 - accuracy: 0.8061
Epoch 2/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.3814 - accuracy: 0.8644
Epoch 3/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.3400 - accuracy: 0.8769
Epoch 4/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.3182 - accuracy: 0.8854
Epoch 5/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.3011 - accuracy: 0.8914
<keras.callbacks.History at 0x7f07b4176850>
net2.evaluate(XX,yy)
313/313 [==============================] - 0s 815us/step - loss: 0.3572 - accuracy: 0.8707
[0.3571898341178894, 0.8707000017166138]
net2.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 27, 27, 30) 150
max_pooling2d (MaxPooling2D (None, 13, 13, 30) 0
)
conv2d_1 (Conv2D) (None, 12, 12, 30) 3630
max_pooling2d_1 (MaxPooling (None, 6, 6, 30) 0
2D)
flatten_1 (Flatten) (None, 1080) 0
dense_5 (Dense) (None, 10) 10810
=================================================================
Total params: 14,590
Trainable params: 14,590
Non-trainable params: 0
_________________________________________________________________
14590/ 1149010
0.012697887746842934
= net2.layers c1, m1, c2, m2, flttn, dns
print(X.shape) # 입력이미지 = 2D
print(c1(X).shape) #2D
print(m1(c1(X)).shape) #2D
print(c2(m1(c1(X))).shape) #2D
print(m2(c2(m1(c1(X)))).shape) #2D
print(flttn(m2(c2(m1(c1(X))))).shape)# 1D
print(dns(flttn(m2(c2(m1(c1(X)))))).shape)# 1D
(60000, 28, 28, 1)
(60000, 27, 27, 30)
(60000, 13, 13, 30)
(60000, 12, 12, 30)
(60000, 6, 6, 30)
(60000, 1080)
(60000, 10)
MaxPool2D
테스트1
-
레이어생성
=tf.keras.layers.MaxPool2D() m
-
입력데이터
= tnp.arange(1*4*4*1).reshape(1,4,4,1)
XXX 1,4,4) XXX.reshape(
<tf.Tensor: shape=(1, 4, 4), dtype=int64, numpy=
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]]])>
흑백 이미지다 생각하고 뒤에 채널 생략하자 걍 보기쉽게
-
입력데이터가 레이어를 통과한 모습
1,2,2) m(XXX).reshape(
<tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
array([[[ 5, 7],
[13, 15]]])>
-
MaxPool2D layer의 역할: (2,2)윈도우를 만들고 (2,2)윈도우에서 max를 뽑아 값을 기록, 윈도우를 움직이면서 반복
테스트2
= tnp.arange(1*6*6*1).reshape(1,6,6,1)
XXX 1,6,6) XXX.reshape(
<tf.Tensor: shape=(1, 6, 6), dtype=int64, numpy=
array([[[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]]])>
1,3,3) m(XXX).reshape(
<tf.Tensor: shape=(1, 3, 3), dtype=int64, numpy=
array([[[ 7, 9, 11],
[19, 21, 23],
[31, 33, 35]]])>
테스트3
=tf.keras.layers.MaxPool2D(pool_size=(3, 3)) m
= tnp.arange(1*6*6*1).reshape(1,6,6,1)
XXX 1,6,6) XXX.reshape(
<tf.Tensor: shape=(1, 6, 6), dtype=int64, numpy=
array([[[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]]])>
1,2,2) m(XXX).reshape(
<tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
array([[[14, 17],
[32, 35]]])>
테스트4
=tf.keras.layers.MaxPool2D(pool_size=(2, 2)) m
= tnp.arange(1*5*5*1).reshape(1,5,5,1)
XXX 1,5,5) XXX.reshape(
<tf.Tensor: shape=(1, 5, 5), dtype=int64, numpy=
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]]])>
1,2,2) m(XXX).reshape(
<tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
array([[[ 6, 8],
[16, 18]]])>
=tf.keras.layers.MaxPool2D(pool_size=(2, 2),padding="same") m
= tnp.arange(1*5*5*1).reshape(1,5,5,1)
XXX 1,5,5) XXX.reshape(
<tf.Tensor: shape=(1, 5, 5), dtype=int64, numpy=
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]]])>
1,3,3) m(XXX).reshape(
<tf.Tensor: shape=(1, 3, 3), dtype=int64, numpy=
array([[[ 6, 8, 9],
[16, 18, 19],
[21, 23, 24]]])>
테스트5
= tnp.arange(2*4*4*1).reshape(2,4,4,1)
XXX 2,4,4) XXX.reshape(
<tf.Tensor: shape=(2, 4, 4), dtype=int64, numpy=
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]],
[[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31]]])>
2,2,2) m(XXX).reshape(
<tf.Tensor: shape=(2, 2, 2), dtype=int64, numpy=
array([[[ 5, 7],
[13, 15]],
[[21, 23],
[29, 31]]])>
테스트6
= tnp.arange(1*4*4*3).reshape(1,4,4,3) XXX
0] XXX[...,
<tf.Tensor: shape=(1, 4, 4), dtype=int64, numpy=
array([[[ 0, 3, 6, 9],
[12, 15, 18, 21],
[24, 27, 30, 33],
[36, 39, 42, 45]]])>
0] m(XXX)[...,
<tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
array([[[15, 21],
[39, 45]]])>
Conv2D
테스트1
-
레이어생성
= tf.keras.layers.Conv2D(1,(2,2)) cnv
-
XXX생성
= tnp.arange(1*4*4*1,dtype=tf.float64).reshape(1,4,4,1)
XXX 1,4,4) XXX.reshape(
<tf.Tensor: shape=(1, 4, 4), dtype=float64, numpy=
array([[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]])>
dytpe이 int형이면 에러가 나므로 float형으로 바꿔주기
1,3,3) cnv(XXX).reshape(
<tf.Tensor: shape=(1, 3, 3), dtype=float32, numpy=
array([[[3.1202679, 3.3676739, 3.61508 ],
[4.109892 , 4.3572974, 4.6047034],
[5.099516 , 5.346921 , 5.594327 ]]], dtype=float32)>
- XXX에서 cnv(XXX)로 가는 맵핑을 찾는건 쉽지 않아보인다.
- 심지어 랜덤으로 결정되는 부분도 있어보임 \(\to\) 계속 값이 바뀜
-
코드정리 + 시드통일
43052)
tf.random.set_seed(= tf.keras.layers.Conv2D(1,(2,2))
cnv = tnp.arange(1*4*4*1,dtype=tf.float64).reshape(1,4,4,1) XXX
-
conv의 입출력
print(XXX.reshape(1,4,4))
print(cnv(XXX).reshape(1,3,3))
tf.Tensor(
[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]]], shape=(1, 4, 4), dtype=float64)
tf.Tensor(
[[[ -5.372491 -6.5789 -7.785309]
[-10.198126 -11.404535 -12.610944]
[-15.023762 -16.230171 -17.436579]]], shape=(1, 3, 3), dtype=float32)
-
conv연산 추론
type(cnv.weights)
list
0],(2,2)) tf.reshape(cnv.weights[
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[-0.2408014 , 0.3118649 ],
[-0.70300657, -0.5744659 ]], dtype=float32)>
0 * -0.2408014 + 1 * 0.3118649 + 4 * -0.70300657 + 5 * -0.5744659 + 0
-5.372490879999999
-
내가 정의한 weights를 대입하여 conv 연산 확인
0].shape cnv.get_weights()[
(2, 2, 1, 1)
= np.array([1/4,1/4,1/4,1/4],dtype=np.float32).reshape(2, 2, 1, 1)
w = np.array([3],dtype=np.float32) b
cnv.set_weights([w,b])
1,4,4) XXX.reshape(
<tf.Tensor: shape=(1, 4, 4), dtype=float64, numpy=
array([[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]])>
1,3,3) cnv(XXX).reshape(
<tf.Tensor: shape=(1, 3, 3), dtype=float32, numpy=
array([[[ 5.5, 6.5, 7.5],
[ 9.5, 10.5, 11.5],
[13.5, 14.5, 15.5]]], dtype=float32)>
0,1,4,5])+3, np.mean([1,2,5,6])+3, np.mean([2,3,6,7])+3 np.mean([
(5.5, 6.5, 7.5)
tf.keras.layers.Conv2D(1,kernel_size=(2,2)) 요약
-
요약
size=(2,2)인 윈도우를 만듬.
XXX에 윈도우를 통과시켜서 (2,2)크기의 sub XXX 를 얻음. sub XXX의 각 원소에 conv2d.weights[0]의 각 원소를 element-wise하게 곱한다.
(2)의 결과를 모두 더한다. 그리고 그 결과에 다시 conv2d.weights[1]을 수행
윈도우를 이동시키면서 반복!
테스트2
-
레이어와 XXX생성
43052)
tf.random.set_seed(= tf.keras.layers.Conv2D(1,(3,3))
cnv = tnp.arange(1*5*5*1,dtype=tf.float64).reshape(1,5,5,1) XXX
1,5,5) ## 입력: XXX XXX.reshape(
<tf.Tensor: shape=(1, 5, 5), dtype=float64, numpy=
array([[[ 0., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 9.],
[10., 11., 12., 13., 14.],
[15., 16., 17., 18., 19.],
[20., 21., 22., 23., 24.]]])>
1,3,3) ## 출력: conv(XXX) cnv(XXX).reshape(
<tf.Tensor: shape=(1, 3, 3), dtype=float32, numpy=
array([[[-3.3962166, -3.7455084, -4.0948005],
[-5.1426764, -5.4919686, -5.84126 ],
[-6.889136 , -7.238429 , -7.5877204]]], dtype=float32)>
0],(1,3,3)) ## 커널의 가중치 tf.reshape(cnv.weights[
<tf.Tensor: shape=(1, 3, 3), dtype=float32, numpy=
array([[[ 0.10026586, -0.17371601, 0.16699821],
[-0.4737161 , 0.19852251, 0.09610051],
[ 0.09313911, -0.29948625, -0.05739981]]], dtype=float32)>
1,5,5)[0,:3,:3] * tf.reshape(cnv.weights[0],(3,3))) tf.reduce_sum(XXX.reshape(
<tf.Tensor: shape=(), dtype=float64, numpy=-3.396216869354248>
테스트3
= tf.constant([[3,3,2,1,0],[0,0,1,3,1],[3,1,2,2,3],[2,0,0,2,2],[2,0,0,0,1]],dtype=tf.float64).reshape(1,5,5,1)
XXX 1,5,5) XXX.reshape(
<tf.Tensor: shape=(1, 5, 5), dtype=float64, numpy=
array([[[3., 3., 2., 1., 0.],
[0., 0., 1., 3., 1.],
[3., 1., 2., 2., 3.],
[2., 0., 0., 2., 2.],
[2., 0., 0., 0., 1.]]])>
= tf.keras.layers.Conv2D(1,(3,3)) cnv
cnv.weights
[]
처음엔 weights가 없다가
1,3,3) cnv(XXX).reshape(
<tf.Tensor: shape=(1, 3, 3), dtype=float32, numpy=
array([[[-0.34136963, -0.7676697 , 2.3211648 ],
[ 1.1140423 , -0.15018106, -0.2899468 ],
[ 0.866542 , -2.0289044 , -1.186438 ]]], dtype=float32)>
0] cnv.weights[
<tf.Variable 'conv2d_8/kernel:0' shape=(3, 3, 1, 1) dtype=float32, numpy=
array([[[[ 0.16768384]],
[[-0.33952343]],
[[-0.37316394]]],
[[[ 0.5341035 ]],
[[ 0.27497447]],
[[-0.38560677]]],
[[[ 0.19056737]],
[[-0.26161364]],
[[ 0.49799764]]]], dtype=float32)>
XXX가 cnv를 통과하면서 weights가 생긴다.
= tf.constant([[0,1,2],[2,2,0],[0,1,2]],dtype=tf.float64).reshape(3,3,1,1)
_w = tf.constant([0],dtype=tf.float64) _b
cnv.set_weights([_w,_b])
1,3,3) cnv(XXX).reshape(
<tf.Tensor: shape=(1, 3, 3), dtype=float32, numpy=
array([[[12., 12., 17.],
[10., 17., 19.],
[ 9., 6., 14.]]], dtype=float32)>
테스트4
43052)
tf.random.set_seed(= tf.keras.layers.Conv2D(1,(2,2))
cnv = tnp.arange(2*5*5*1,dtype=tf.float64).reshape(2,5,5,1) XXX
print(XXX.reshape(2,5,5))
# weights를 초기화 시키기 위해서 레이어를 1회 통과
cnv(XXX)
cnv.set_weights([w,b])print(cnv(XXX).reshape(2,4,4))
tf.Tensor(
[[[ 0. 1. 2. 3. 4.]
[ 5. 6. 7. 8. 9.]
[10. 11. 12. 13. 14.]
[15. 16. 17. 18. 19.]
[20. 21. 22. 23. 24.]]
[[25. 26. 27. 28. 29.]
[30. 31. 32. 33. 34.]
[35. 36. 37. 38. 39.]
[40. 41. 42. 43. 44.]
[45. 46. 47. 48. 49.]]], shape=(2, 5, 5), dtype=float64)
tf.Tensor(
[[[ 6. 7. 8. 9.]
[11. 12. 13. 14.]
[16. 17. 18. 19.]
[21. 22. 23. 24.]]
[[31. 32. 33. 34.]
[36. 37. 38. 39.]
[41. 42. 43. 44.]
[46. 47. 48. 49.]]], shape=(2, 4, 4), dtype=float32)
0,1,5,6])+3,np.mean([25,26,30,31])+3, np.mean([
(6.0, 31.0)
테스트5
-
43052)
tf.random.set_seed(= tf.keras.layers.Conv2D(4,(2,2),activation='relu')
cnv = tnp.arange(1*2*2*1,dtype=tf.float64).reshape(1,2,2,1) XXX
print(XXX.reshape(1,2,2))
tf.Tensor(
[[[0. 1.]
[2. 3.]]], shape=(1, 2, 2), dtype=float64)
cnv(XXX)
<tf.Tensor: shape=(1, 1, 1, 4), dtype=float32, numpy=
array([[[[1.7573347 , 0.84183925, 1.7484205 , 0. ]]]],
dtype=float32)>
0] # (2,2) 커널의 크기 // 1은 XXX의 채널수 // 4는 conv(XXX)의 채널수 cnv.weights[
<tf.Variable 'conv2d_10/kernel:0' shape=(2, 2, 1, 4) dtype=float32, numpy=
array([[[[-0.00448787, 0.17636931, 0.17748284, 0.5281223 ]],
[[-0.01255804, 0.0121181 , -0.1567888 , 0.513507 ]]],
[[[ 0.3668834 , 0.32297856, 0.32239443, -0.5187031 ]],
[[ 0.3453753 , 0.06125468, 0.42014015, -0.36382926]]]],
dtype=float32)>
0][...,0].reshape(2,2) ## conv(XXX)의 첫번째채널 출력을 얻기 위해 곱해지는 w cnv.weights[
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[-0.08230966, -0.36398047],
[ 0.19759327, 0.33916563]], dtype=float32)>
1,2,2) * cnv.weights[0][...,0].reshape(2,2)) ### conv(XXX)의 첫번째 채널 출력결과 tf.reduce_sum(XXX.reshape(
<tf.Tensor: shape=(), dtype=float64, numpy=1.0487029552459717>
-
계산결과를 확인하기 쉽게 하기 위한 약간의 트릭
43052)
tf.random.set_seed(= tf.keras.layers.Conv2D(4,(2,2))
cnv = tnp.array([1]*1*2*2*1,dtype=tf.float64).reshape(1,2,2,1) XXX
print(XXX.reshape(1,2,2))
tf.Tensor(
[[[1. 1.]
[1. 1.]]], shape=(1, 2, 2), dtype=float64)
- 이렇게 XXX를 설정하면 cnv(XXX)의 결과는 단지 cnv의 weight들의 sum이 된다.
cnv(XXX)
<tf.Tensor: shape=(1, 1, 1, 4), dtype=float32, numpy=
array([[[[ 0.09046876, -0.6207629 , -0.25241536, -0.7710641 ]]]],
dtype=float32)>
0] # (2,2) 커널의 크기 // 1은 XXX의 채널수 // 4는 conv(XXX)의 채널수 cnv.weights[
<tf.Variable 'conv2d_24/kernel:0' shape=(2, 2, 1, 4) dtype=float32, numpy=
array([[[[-0.08230966, -0.15132892, -0.12760344, -0.38952267]],
[[-0.36398047, 0.07347518, -0.08780673, 0.46633136]]],
[[[ 0.19759327, -0.46042526, -0.15406173, -0.34838456]],
[[ 0.33916563, -0.08248386, 0.11705655, -0.49948823]]]],
dtype=float32)>
0][...,0].reshape(2,2) ## conv(XXX)의 첫번째채널 출력을 얻기 위해 곱해지는 w cnv.weights[
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[-0.08230966, -0.36398047],
[ 0.19759327, 0.33916563]], dtype=float32)>
0][...,0])
tf.reduce_sum(cnv.weights[#tf.reduce_sum(XXX.reshape(1,2,2) * cnv.weights[0][...,0].reshape(2,2)) ### conv(XXX)의 첫번째 채널 출력결과
<tf.Tensor: shape=(), dtype=float32, numpy=0.090468764>
테스트6
-
결과확인을 쉽게하기 위해서 XXX를 1로 통일
43052)
tf.random.set_seed(= tf.keras.layers.Conv2D(4,(2,2))
cnv = tnp.array([1]*1*2*2*3,dtype=tf.float64).reshape(1,2,2,3) XXX
cnv(XXX)
<tf.Tensor: shape=(1, 1, 1, 4), dtype=float32, numpy=
array([[[[ 0.3297621, -0.4498347, -1.0487393, -1.580095 ]]]],
dtype=float32)>
0] ## (2,2)는 커널의 사이즈 // 3은 XXX의채널 // 4는 cnv(XXX)의 채널 cnv.weights[
<tf.Variable 'conv2d_33/kernel:0' shape=(2, 2, 3, 4) dtype=float32, numpy=
array([[[[-0.06956434, -0.12789628, -0.10784459, -0.32920673],
[-0.30761963, 0.06209785, -0.07421023, 0.3941219 ],
[ 0.16699678, -0.38913035, -0.13020593, -0.29443866]],
[[ 0.28664726, -0.0697116 , 0.09893084, -0.4221446 ],
[-0.23161241, -0.16410837, -0.36420006, 0.12424195],
[-0.14245945, 0.36286396, -0.10751781, 0.1733647 ]]],
[[[ 0.02764335, 0.15547717, -0.42024496, -0.31893867],
[ 0.22414821, 0.3619454 , -0.00282967, -0.3503708 ],
[ 0.4610079 , -0.17417148, 0.00401336, -0.29777044]],
[[-0.1620284 , -0.42066965, -0.01578814, -0.4240524 ],
[ 0.37925082, 0.24236053, 0.3949356 , -0.20996472],
[-0.30264795, -0.28889188, -0.3237777 , 0.37506342]]]],
dtype=float32)>
0][...,0] ## cnv(XXX)의 첫번째 채널결과를 얻기 위해서 사용하는 w cnv.weights[
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy=
array([[[-0.06956434, -0.30761963, 0.16699678],
[ 0.28664726, -0.23161241, -0.14245945]],
[[ 0.02764335, 0.22414821, 0.4610079 ],
[-0.1620284 , 0.37925082, -0.30264795]]], dtype=float32)>
0][...,0]) ### cnv(XXX)의 첫번째 채널의 결과 tf.reduce_sum(cnv.weights[
<tf.Tensor: shape=(), dtype=float32, numpy=0.32976213>
print(tf.reduce_sum(cnv.weights[0][...,0]))
print(tf.reduce_sum(cnv.weights[0][...,1]))
print(tf.reduce_sum(cnv.weights[0][...,2]))
print(tf.reduce_sum(cnv.weights[0][...,3])) ### cnv(XXX)의 결과
tf.Tensor(0.32976213, shape=(), dtype=float32)
tf.Tensor(-0.44983464, shape=(), dtype=float32)
tf.Tensor(-1.0487392, shape=(), dtype=float32)
tf.Tensor(-1.5800952, shape=(), dtype=float32)
= cnv.weights[0][...,0][...,0]
w_red = cnv.weights[0][...,0][...,1]
w_green = cnv.weights[0][...,0][...,2] w_blue
0] * w_red + XXX[...,1] * w_green + XXX[...,2] * w_blue) ## cnv(XXX)의 첫채널 출력결과 tf.reduce_sum(XXX[...,
<tf.Tensor: shape=(), dtype=float64, numpy=0.32976213097572327>
hw
아래와 같은 흑백이미지가 있다고 하자.
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
위의 이미지에 아래와 같은 weight를 가진 필터를 적용하여 convolution한 결과를 계산하라. (bias는 0으로 가정한다)
-1 1
-1 1