tf.keras.layers.Layer
와 tf.keras.layers.Model
클래스이다.tf.keras.layers.Model
클래스의 경우 모델을 저장 하는 기능과 fit
함수를 사용할 수 있다는 점에서 차이가 있다.import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
np.random.seed(7777)
tf.random.set_seed(7777)
class LinearRegression(tf.keras.layers.Layer):
def __init__(self, units): #units 몇 개 output
super(LinearRegression, self).__init__() # 부모 상속
self.units = units
def build(self, input_shape): # input_shape w크기 결정
self.w = self.add_weight( # Layer에 있는 add_weight함수
shape=(input_shape[-1], self.units),
initializer="random_normal",
trainable=True,
)
self.b = tf.Variable(0.0) #def로 만드는 것을 추천
def call(self, inputs): # w * x + b
return tf.matmul(inputs, self.w) + self.b
W_true = np.array([[3., 2., 4., 1.]]).reshape((4, 1)) #현재 만들고자 하는 rank 2라서 맞추기
B_true = np.array([1.])
X = tf.random.normal((500, 4)) #feature 4개
noise = tf.random.normal((500, 1))
y = X @ W_true + B_true + noise
opt = tf.keras.optimizers.SGD(learning_rate=3e-2) #0.03
linear_layer = LinearRegression(1) #units=1
for epoch in range(100):
with tf.GradientTape() as tape:
y_hat = linear_layer(X)
loss = tf.reduce_mean(tf.square((y - y_hat))) #mse
grads = tape.gradient(loss, linear_layer.trainable_weights)
# w.assign_sub(lr*dw)을 아래 방식으로
opt.apply_gradients(zip(grads, linear_layer.trainable_weights))
if epoch % 10 == 0:
print("epoch : {} loss : {}".format(epoch, loss.numpy()))
1) Residual Block - Layer
2) ResNet - Model
from tensorflow.keras.layers import Input, Conv2D, MaxPool2D, Flatten, Dense, Add
class ResidualBlock(tf.keras.layers.Layer):
def __init__(self, filters=32, filter_match=False): #net_1_1 역할
super(ResidualBlock, self).__init__()
self.conv1 = Conv2D(filters, kernel_size=1, padding='same', activation='relu')
self.conv2 = Conv2D(filters, kernel_size=3, padding='same', activation='relu')
self.conv3 = Conv2D(filters, kernel_size=1, padding='same', activation='relu')
self.add = Add()
self.filters = filters
self.filter_match = filter_match
if filter_match:
self.conv_ext = Conv2D(filters, kernel_size=1, padding='same')
def call(self, inputs):
net1 = self.conv1(inputs)
net2 = self.conv2(net1)
net3 = self.conv3(net2)
if self.filter_match:
res = self.add([self.conv_ext(inputs), net3])
else:
res = self.add([inputs, net3])
return res
class ResNet(tf.keras.Model):
def __init__(self, num_classes):
super(ResNet, self).__init__()
self.conv1 = Conv2D(32, kernel_size=3, strides=2, padding='same', activation='relu')
self.maxp1 = MaxPool2D()
self.block_1 = ResidualBlock(64, True)
self.block_2 = ResidualBlock(64)
self.maxp2 = MaxPool2D()
self.flat = Flatten()
self.dense = Dense(num_classes)
def call(self, inputs):
x = self.conv1(inputs)
x = self.maxp1(x)
x = self.block_1(x)
x = self.block_2(x)
x = self.maxp2(x)
x = self.flat(x)
return self.dense(x)
model = ResNet(num_classes=10)
Reference
1) 제로베이스 데이터스쿨 강의자료