(11주차) 5월16일
import tensorflow as tf
import tensorflow.experimental.numpy as tnp
import numpy as np
tf.experimental.numpy.experimental_enable_numpy_behavior()
conv2d=tf.keras.layers.Conv2D(1,(2,2))
XXX= tnp.arange(1*4*4*1,dtype=tf.float64).reshape(1,4,4,1)
XXX
conv2d(XXX)
- 에러가 생기는경우
XXX= tnp.arange(1*4*4,dtype=tf.float64).reshape(1,4,4)
XXX
conv2d(XXX)
XXX= tnp.arange(1*4*4*1).reshape(1,4,4,1)
XXX
conv2d(XXX)
- float16,32,64는 에러가 나지 않음
XXX= tnp.arange(1*4*4*1,dtype=tf.float16).reshape(1,4,4,1)
conv2d(XXX)
XXX= tnp.arange(1*4*4*1,dtype=tf.float32).reshape(1,4,4,1)
conv2d(XXX)
XXX= tnp.arange(1*4*4*1,dtype=tf.float64).reshape(1,4,4,1)
conv2d(XXX)
- 첫시도
XXX= tnp.arange(1*4*4*1,dtype=tf.float64).reshape(1,4,4,1)
XXX.reshape(1,4,4)
conv2d(XXX).reshape(1,3,3)
- XXX에서 conv2d(XXX)로 가는 규칙이 무엇일까?
- 코드의정리 -> 랜덤으로 바뀌는 부분이 있어서 seed고정
tf.random.set_seed(43052)
XXX= tnp.arange(1*4*4*1,dtype=tf.float64).reshape(1,4,4,1)
conv2d = tf.keras.layers.Conv2D(1,(2,2))
print(XXX.reshape(1,4,4))
print(conv2d(XXX).reshape(1,3,3))
tf.reshape(conv2d.weights[0],(2,2))
0 * -0.13014299 + 1 * -0.23927206 + 4 * -0.20175874 + 5 * -0.6158894
- 결과 관찰하는 것이 힘드니까 에이트를 조정해보자.
conv2d.get_weights()
conv2d.get_weights()[0].shape
w= np.array([1/4,1/4,1/4,1/4],dtype=np.float32).reshape(2,2,1,1)
conv2d.get_weights()[1].shape
b= np.array([3],dtype=np.float32)
conv2d.set_weights([w,b])
conv2d.get_weights()
print(XXX.reshape(1,4,4))
print(conv2d(XXX).reshape(1,3,3))
(0+1+4+5)/4 +3, (1+2+5+6)/4 +3, (2+3+6+7)/4 +3
- 요약
(1) size=(2,2)인 윈도우를 만듬.
(2) XXX에 윈도우를 통과시켜서 (2,2)크기의 sub XXX 를 얻음. sub XXX의 각 원소에 conv2d.weights[0]의 각 원소를 element-wise하게 곱한다.
(3) (2)의 결과를 모두 더한다. 그리고 그 결과에 다시 conv2d.weights[1]을 수행
(4) 윈도우를 이동시키면서 반복!
- XXX의 관측치가 여러개라면?
XXX = tnp.arange(2*4*4*1,dtype=tf.float64).reshape(2,4,4,1)
XXX.reshape(2,4,4)
conv2d(XXX).reshape(2,3,3)
(16+17+20+21)/4 + 3
- 윈도우의 크기가 (3,3)이라면?
XXX = tnp.array([1]*1*4*4*1,dtype=tf.float64).reshape(1,4,4,1)
XXX.reshape(1,4,4)
- 이렇게하면 conv의 결과과 weight의 sum이 나오므로 확인하기 쉽다.
conv2d = tf.keras.layers.Conv2D(1,(3,3))
conv2d(XXX).reshape(1,2,2)
tf.reduce_sum(tf.reshape(conv2d.weights[0],(3,3)))

XXX = 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
conv2d = tf.keras.layers.Conv2D(1,(3,3))
conv2d.get_weights()
conv2d(XXX)
conv2d.get_weights()[0].shape
_w = np.array([[0,1,2],[2,2,0],[0,1,2]],dtype=np.float32).reshape(3, 3, 1, 1)
_b = np.array([0],dtype=np.float32)
conv2d.set_weights([_w,_b])
conv2d(XXX).reshape(1,3,3)
- conv2의 채널이 여러개라면?
XXX = tnp.array([1]*1*2*2*1,dtype=tf.float64).reshape(1,2,2,1)
XXX.reshape(1,2,2)
conv2d = tf.keras.layers.Conv2D(4,(2,2))
conv2d(XXX)
conv2d(XXX).shape
- conv2d : (2,2,1) -> (1,1,4) 로 바꾸는 변환
np.array(conv2d.weights[0])[...,0].sum() ## conv2d(XXX)의 첫번째 채널
np.array(conv2d.weights[0])[...,1].sum() ## conv2d(XXX)의 두번째 채널
np.array(conv2d.weights[0])[...,2].sum() ## conv2d(XXX)의 세번째 채널
np.array(conv2d.weights[0])[...,3].sum() ## conv2d(XXX)의 네번째 채널
- X의 채널도 여러개이고, conv2의 채널도 여러개라면?
XXX = tnp.array([1]*1*2*2*3,dtype=tf.float64).reshape(1,2,2,3)
conv2d = tf.keras.layers.Conv2D(4,(2,2))
conv2d(XXX)
- conv2d: (2,2,3) -> (1,1,4) 로 만들어 주는 변환
conv2d.weights ## 처음 (2,2)는 window size // 3은 XXX의 채널수 // 4는 conv(XXX)의 채널수
print(conv2d(XXX))
print(np.array(conv2d.weights[0])[...,0].sum())
print(np.array(conv2d.weights[0])[...,1].sum())
print(np.array(conv2d.weights[0])[...,2].sum())
print(np.array(conv2d.weights[0])[...,3].sum())
W_red = np.array(conv2d.weights[0])[...,0][...,0]
W_green = np.array(conv2d.weights[0])[...,0][...,1]
W_blue = np.array(conv2d.weights[0])[...,0][...,2]
(W_red+W_green+W_blue).sum() ### convXXX의 첫채널 결과
W_red = np.array(conv2d.weights[0])[...,1][...,0]
W_green = np.array(conv2d.weights[0])[...,1][...,1]
W_blue = np.array(conv2d.weights[0])[...,1][...,2]
(W_red+W_green+W_blue).sum() ### convXXX의 두번째 채널 결과
아래와 같은 흑백이미지가 있다고 하자.
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