728x90

텐서플로 선형 분류기

num_samples_per_class = 1000  
negative_samples = np.random.multivariate_normal(  
    mean=[0, 3],  
    cov=[[1, 0.5], [0.5, 1]],  
    size=num_samples_per_class  
)  
positive_samples = np.random.multivariate_normal(  
    mean=[3, 0],  
    cov=[[1, 0.5], [0.5, 1]],  
    size=num_samples_per_class  
)  
  
  
inputs = np.vstack((negative_samples, positive_samples)).astype(np.float32)  
  
targets = np.vstack((np.zeros((num_samples_per_class, 1), dtype="float32"),  
                    np.ones((num_samples_per_class, 1), dtype="float32")))  
  
# plt.scatter(inputs[:, 0], inputs[:, 1], c=targets[: ,0])  
# plt.show()

모델 설정 및 학습

# 선형 분류기의 변수 만들기  
input_dim = 2  
output_dim = 1  
  
W = tf.Variable(initial_value=tf.random.uniform(shape=(input_dim, output_dim)))  
b = tf.Variable(initial_value=tf.zeros(shape=(output_dim,)))  
  
# 정방향 패스 함수  
def model(inputs):  
    return tf.matmul(inputs, W) + b  
  
# 평균 제곱 오차 손실 함수  
def square_loss(targets, predictions):  
    per_sample_losses = tf.square(targets - predictions)  
    return tf.reduce_mean(per_sample_losses)  
  
# 훈련 스텝 함수  
learning_rate = 0.1  
  
def training_step(inputs, targets):  
    with tf.GradientTape() as tape:  
        predictions = model(inputs)  
        loss = square_loss(targets, predictions)  
  
    grad_loss_wrt_W, grad_loss_wrt_b = tape.gradient(loss, [W, b])  
    W.assign_sub(grad_loss_wrt_W * learning_rate)  
    b.assign_sub(grad_loss_wrt_b * learning_rate)  
  
    return loss  
  
# 배치 훈련 룹  
for step in range(40):  
    loss = training_step(inputs, targets)  
    print(f"{step} 번째 스텝의 손실: {loss:.4f}")  
  
  
predictions = model(inputs)  
# plt.scatter(inputs[:, 0], inputs[:, 1], c=predictions[:, 0] > 0.5)  
# plt.show()  
  
x = np.linspace(-1, 4, 100)  
y = - W[0] / W[1] * x + (0.5 - b) / W[1]  
plt.plot(x, y, "-r")  
plt.scatter(inputs[:, 0], inputs[:, 1], c=predictions[:, 0] > 0.5)  
plt.show()

Tensorflow Simple Dense

class SimpleDense(keras.layers.Layer):
    def __init__(self, units, activation=None):
        super().__init__()
        self.units = units
        self.activation = activation
    
    
    def build(self, input_shape):
        input_dim = input_shape[-1]
        self.W = self.add_weight(shape=(input_dim, self.units),
                                 initializer="random_normal")
        self.b = self.add_weight(shape=(self.units,),
                                 initializer="zeros")
        
    
    def call(self, inputs): # inputs: 
    특징 데이터
        y = tf.matmul(inputs, self.W) + self.b
        if self.activation is not None:
            y = self.activation(y)
            
        return y
  • unit: neuron

출력층의 활성화 함수
이진분류 : 시그모이드
다중분류 : 소프트맥스

  • 노드 1개당 bias 1개 있음
  • zeros : 0값으로 bias설정
  • matmul : 행렬곱
class FashionCNN(nn.Module):
    def __init__(self):
        super(FashionCNN, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1),
            nn.BatchNorm2d(32),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)
            )
        
        self.layer2 = nn.Sequential(
            nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(2)
            )
        
        self.fc1 = nn.Linear(in_features=64*6*6, out_features=600)
        self.drop = nn.Dropout2d(0.25)
        self.fc2 = nn.Linear(in_features=600, out_features=120)
        self.fc3 = nn.Linear(in_features=120, out_features=10)
        
    
    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.view(out.size(0), -1)
        out = self.fc1(out)
        out = self.drop(out)
        out = self.fc2(out)
        out = self.fc3(out)
        
        return out
  • in_channels=1 흑백

  • 3x3커널 32개로 계산

  • nn.MaxPool2d(2) : 커널 사이즈

  • in_features=64x6x6 은 6 by 6이 64장있는 것(마지막 레이어에 64가 out이었음)을 flatten한것

  • out = out.view(out.size(0), -1)
    -> 실제 flatten 과정이 여기서 일어남 (1차원으로 바꾸기)

  • shape(배치크기, 채널, 행, 열)

  • nn.Sequential을 사용하면 init에서 네트워크 모델을 정의하고 forward()에서 구현될 순전파를 layer 형태로 가독성있게 작성

  • nn.Conv2d 합성곱층(conv layer)은 합성곱 연산을 통해서 이미지의 특징을 추출

  • MaxPool2d는 이미기 크기를 축소시키는 용도

FashionCNN(
(layer1): Sequential(
(0): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU()
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(layer2): Sequential(
(0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU()
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(fc1): Linear(in_features=2304, out_features=600, bias=True)
(drop): Dropout2d(p=0.25, inplace=False)
(fc2): Linear(in_features=600, out_features=120, bias=True)
(fc3): Linear(in_features=120, out_features=10, bias=True)
)

반응형