
๋ฅ๋ฌ๋ ํ๋ ์์ํฌ์ ์ผ์ข
C/C++๋ก ๊ตฌํ๋์ด ์๊ณ ํ์ด์ฌ์ ๋น๋กฏํ์ฌ ์ฌ๋ฌ ๊ฐ์ง ์ธ์ด์์ ์ ๊ทผํ ์ ์๋๋ก ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.ํ
์๋ ๋ค์ฐจ์ ๋ฐฐ์ด (์ค์นผ๋ผ, ๋ฒกํฐ, ํ๋ ฌ ํ
์)์ ๋ํ๋ด๋ฉฐ ํ๋ก์ฐ๋ Data Flow์ ์๋ฏธ๋ก ์ ๋๋ค ์ฌ์ด๋ก ํ
์๋ค์ด ํ๋ฌ๋ค๋๋ค๋ ๋ป์ด๋ค.

ํ์ด์ฌ์ผ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๊ณ ์์ค ๋ฅ๋ฌ๋ API์ด๋ค.
ํ
์ํ๋ก์ฐ์ด๋ค.ํผ๋ํฌ์๋ ์ ๊ฒฝ๋ง, ์ปจ๋ณผ๋ฃจ์
์ ๊ฒฝ๋ง๊ณผ ์ํ ์ ๊ฒฝ๋ง์ ๋ฌผ๋ก , ์ฌ๋ฌ ๊ฐ์ง์ ์กฐํฉ๋ ์ง์ํ๋ค.CPU ๋ฐ GPU์์ ์ํํ๊ฒ ์คํ๋๋ค.ํ์ดํ ์น(pytorch)๋ ์ฐ๊ตฌ์๋ค์ด ์ ํธํ๋ค.
๋ชจ๋ธ(model)์ด๋ฉฐ ๋ ์ด์ด๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํ๋ธ๋ค.Sequential ์ ํ ์คํ ๋ชจ๋ธ์ด๋ค. Sequential ๋ชจ๋ธ์ ๋ ์ด์ด๋ฅผ ์ ํ์ผ๋ก ์์ ์ ์๋ ์ ๊ฒฝ๋ง ๋ชจ๋ธ์ด๋ค.

# (1) ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํฌํจ
import numpy as np
import tensorflow as tf
# (2) ์
๋ ฅ๋ฐ์ดํฐ์ ์ ๋ต ๋ ์ด๋ธ์ ์ค๋น (Numpy ๋ฐฐ์ด์ด๋ Python listํ์์ผ๋ก ์ค๋น)
X = np.array([[0,0], [0,1], [1,0], [1,1]]) # XOR ๋ฌธ์ ์ ์
๋ ฅ ๋ฐ์ดํฐ
y = np.array([[0], [1], [1], [0]]) # XOR ๋ฌธ์ ์ ์ ๋ต ๋ ์ด๋ธ
# (3) Sequential ๋ชจ๋ธ์ ์์ฑ
model = tf.keras.models.Sequential()
# (4) Sequential ๋ชจ๋ธ์ add() ํจ์๋ฅผ ์ด์ฉํ์ฌ ํ์ํ ๋ ์ด์ด๋ฅผ ์ถ๊ฐ
model.add(tf.keras.layers.Dense(units=2, input_shape=(2,), activation='sigmoid')) # ์ฒซ ๋ฒ์งธ ์๋์ธต, 2๊ฐ์ ์ ๋
model.add(tf.keras.layers.Dense(units=1, activation='sigmoid')) # ์ถ๋ ฅ์ธต, 1๊ฐ์ ์ ๋
# (5) compile() ํจ์๋ฅผ ํธ์ถํ์ฌ Sequential ๋ชจ๋ธ์ ์ปดํ์ผ
model.compile(loss='mean_squared_error', optimizer=tf.keras.optimizers.SGD(learning_rate=0.3))
# loss function์ MSE, learning rate=0.3
# (6) fit()๋ฅผ ํธ์ถํ์ฌ์ ํ์ต์ ์ํ
model.fit(X, y, batch_size=1, epochs=1000) # ๋ฐฐ์น ํฌ๊ธฐ 1, ์ํฌํฌ 1000๋ฒ
# (7) predict()๋ฅผ ํธ์ถํ์ฌ ๋ชจ๋ธ์ ํ
์คํธ
print(model.predict(X)) # ์์ธก๋ ์ถ๋ ฅ ๊ฐ
# (8) summary()ํจ์๋ก ๋ชจ๋ธ ํ๋ผ๋ฏธํฐ ์ ์ ๊ฒ
print(model.summary()) # ๋ชจ๋ธ ์์ฝ ์ ๋ณด ์ถ๋ ฅ
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 2) 6
_________________________________________________________________
dense_1 (Dense) (None, 1) 3
=================================================================
Total params: 9
Trainable params: 9
Non-trainable params: 0
_________________________________________________________________
model = Sequential()
model.add(Dense(units=2, input_shape=(2,), activation='sigmoid'))
model.add(Dense(units=1, activation='sigmoid'))

inputs = Input(shape=(2,)) # ์
๋ ฅ์ธต
x = Dense(2, activation="sigmoid")(inputs) # ์๋์ธต
prediction = Dense(1, activation="sigmoid")(x) # ์ถ๋ ฅ์ธต
model = Model(inputs=inputs, outputs=prediction)
ํจ์ํ API๋ฅผ ์ฌ์ฉํ๋ฉด ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉ์์ผ๋ก ๊ฐ์ฒด๋ค์ ์ฐ๊ฒฐํ ์ ์์ผ๋ฉฐ ๋ ์ด์ด๊ฐ ๋ค์ค ์
๋ ฅ์ด๋ ๋ค์ค ์ถ๋ ฅ์ ๊ฐ์ง๋๋ก ์ฐ๊ฒฐํ ์๋ ์๋ค.
class SimpleMLP(Model):
def __init__(self, num_classes): # ์์ฑ์ ์์ฑ
super(SimpleMLP, self).__init__(name='mlp')
self.num_classes = num_classes
self.dense1 = Dense(32, activation='sigmoid')
self.dense2 = Dense(num_classes, activation='sigmoid')
def call(self, inputs): # ์๋ฐฉํฅ ํธ์ถ์ ๊ตฌํํ๋ค
x = self.dense1(inputs)
return self.dense2(x)
model = SimpleMLP()
model.compile(...) # ์์คํจ์, ์ต์ ํ๊ธฐ, ํ๊ฐ์งํ ๋ฑ ์ค์
model.fit(...) # ํ์ต ์ํ

1980๋ ๋์ ๋ฏธ๊ตญ์ ๊ตญ๋ฆฝํ์ค ์ฐ๊ตฌ์(NIST)์์ ์์งํ ๋ฐ์ดํฐ ์ธํธ๋ก
6๋ง๊ฐ์ ํ๋ จ ์ด๋ฏธ์ง์1๋ง๊ฐ์ ํ ์คํธ ์ด๋ฏธ์ง๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
# ์ซ์ ๋ฐ์ดํฐ ๊ฐ์ ์ค๊ธฐ
import matplotlib.pyplot as plt
import tensorflow as tf
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
# numpy ๋ฐฐ์ด ํํ ์ถ๋ ฅ
train_images.shape
#(60000, 28, 28)
train_labels
#array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
test_images.shape
#(10000, 28, 28)
plt.imshow(train_images[0], cmap="Greys")

# ์ ๊ฒฝ๋ง ๋ชจ๋ธ ๊ตฌ์ถ
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(512, activation='relu', input_shape=(784,))) # 512 units, input shape 28*28=784
model.add(tf.keras.layers.Dense(10, activation='sigmoid')) # 10 units, sigmoid activation function
model.compile(optimizer='rmsprop',loss='mse', metrics=['accuracy'])
์์คํจ์(loss function): ์ ๊ฒฝ๋ง์ ์ถ๋ ฅ๊ณผ ์ ๋ต ๊ฐ์ ์ค์ฐจ๋ฅผ ๊ณ์ฐํ๋ ํจ์ [mse]์ตํฐ๋ง์ด์ (optimizer): ์์ค ํจ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ๊ฒฝ๋ง์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ต์ ํํ๋ ์๊ณ ๋ฆฌ์ฆ [rmsprop]์งํ(metric): ํ๋ จ๊ณผ ํ
์คํธ ๊ณผ์ ์์ ์ฌ์ฉ๋๋ ์ฒ๋ [accuracy]
# ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
train_images = train_images.reshape((60000, 784))
train_images = train_images.astype('float32') / 255.0
test_images = test_images.reshape((10000, 784))
test_images = test_images.astype('float32') / 255.0

# ์ ๋ต ๋ ์ด๋ธ ํํ ๋ณ๊ฒฝ(์ํซ ์ธ์ฝ๋ฉ)
train_labels = tf.keras.utils.to_categorical(train_labels)
test_labels = tf.keras.utils.to_categorical(test_labels)
# train_labels[0]
# array([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], dtype=float32)

# ํ์ต
history = model.fit(train_images, train_labels, epochs=5, batch_size=128)
Epoch 1/5
469/469 [==============================] - 2s 3ms/step - loss: 0.0158 - accuracy: 0.9168
...
Epoch 5/5
469/469 [==============================] - 2s 3ms/step - loss: 0.0027 - accuracy: 0.9867
# ํ
์คํธ
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('ํ
์คํธ ์ ํ๋:', test_acc)
313/313 [==============================] - 0s 892us/step - loss: 0.0039 - accuracy: 0.9788
ํ
์คํธ ์ ํ๋: 0.9787999987602234
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
loss = history.history['loss']
acc = history.history['accuracy']
epochs = range(1, len(loss)+1)
plt.plot(epochs, loss, 'b', label='Training Loss')
plt.plot(epochs, acc, 'r', label='Accuracy')
plt.xlabel('epochsโ)
plt.ylabel('loss/accโ)
plt.show()

# ์ค์ ์ด๋ฏธ์ง๋ก ํ
์คํธํ๊ธฐ
from google.colab import drive
drive.mount('/content/drive')
# Mounted at /content/drive
import os
print(os.listdir('/content/drive/MyDriveโ))
# ['Colab Notebooks', 'Google Formโ,โฆ]
# ์ค์ ์ด๋ฏธ์ง๋ก ํ
์คํธํ๊ธฐ
import cv2 as cv
image = cv.imread('test.png', cv.IMREAD_GRAYSCALE)
image = cv.resize(image, (28, 28))
image = image.astype('float32')
image = image.reshape(1, 784)
image = 255-image
image /= 255.0
plt.imshow(image.reshape(28, 28),cmap='Greys')
plt.show()
pred = model.predict(image.reshape(1, 784), batch_size=1)
print("์ถ์ ๋ ์ซ์=", pred.argmax())

์ถ์ ๋ ์ซ์= 2
์ผ๋ผ์ค์ ์
๋ ฅ ๋ฐ์ดํฐ
๋ํ์ด ๋ฐฐ์ด: ๋ฉ๋ชจ๋ฆฌ์ ์ ์ ๊ฐ๋ฅํ๋ฉด ์ข์ ์ ํ์ด๋ค.TensorFlow Dataset ๊ฐ์ฒด: ํฌ๊ธฐ๊ฐ ์ปค์, ๋ฉ๋ชจ๋ฆฌ์ ํ ๋ฒ์ ์ ์ฌ๋ ์ ์๋ ๊ฒฝ์ฐ์ ๋์คํฌ ๋๋ ๋ถ์ฐ ํ์ผ ์์คํ
์์ ์คํธ๋ฆฌ๋ฐ๋ ์ ์๋ค.ํ์ด์ฌ ์ ๋๋ ์ดํฐ: ์๋ฅผ ๋ค์ด์ keras.utils.Sequence ํด๋์ค๋ ํ๋ ๋์คํฌ์ ์์นํ ํ์ผ์ ์ฝ์ด์ ์์ฐจ์ ์ผ๋ก ์ผ๋ผ์ค ๋ชจ๋ธ๋ก ๊ณต๊ธํ ์ ์๋ค.ํ
์(tensor)๋ ๋ค์ฐจ์ ๋ํ์ด ๋ฐฐ์ด์ด๋ค.
3์ฐจ์ ์ด์์ ์ ํต์ ์ผ๋ก ํ
์(tensor)๋ผ๊ณ ๋ถ๋ ค์๋ค.์ปจํ
์ด๋๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.ํ ์(tensor)์ ์์ฑ
ํ
์์ ์ฐจ์(์ถ์ ๊ฐ์): ํ
์์ ์กด์ฌํ๋ ์ถ์ ๊ฐ์๋ก 3์ฐจ์ ํ
์์๋ 3๊ฐ์ ์ถ์ด ์๋ค. [x.ndim]ํ์(shape): ํ
์์ ๊ฐ ์ถ์ผ๋ก ์ผ๋ง๋ ๋ฐ์ดํฐ๊ฐ ์๋์ง๋ฅผ ํ์ด์ฌ์ ํํ๋ก ๋ํ๋ธ ๊ฒ์ด๋ค. [x.shape]๋ฐ์ดํฐ ํ์
(data type): ํ
์ ์์์ ์๋ฃํ [x.dtype]
import numpy as np
x = np.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]]]
)
x.ndim
# 3
x.shape
# (3, 2, 5)
x.dtype
# dtype('int64')

๋ฒกํฐ ๋ฐ์ดํฐ: (๋ฐฐ์น ํฌ๊ธฐ, ํน์ง์) ํ์์ 2์ฐจ์ ๋ํ์ด ํ
์์ ์ ์ฅ๋๋ค.(batch_size, features)=(365,3)

์ด๋ฏธ์ง ๋ฐ์ดํฐ: (๋ฐฐ์น ํฌ๊ธฐ, ์ด๋ฏธ์ง ๋์ด, ์ด๋ฏธ์ง ๋๋น, ์ฑ๋์) ํ์์ 4์ฐจ์ ๋ํ์ด ํ
์์ ์ ์ฅ๋๋ค(batch_size, height, width, channels)=c(365,28,28,3)

์๊ณ์ด ๋ฐ์ดํฐ: (๋ฐฐ์น ํฌ๊ธฐ, ํ์
์คํ
, ํน์ง์) ํ์์ 3์ฐจ์ ๋ํ์ด ํ
์์ ์ ์ฅ๋๋ค.(batch_size, timesteps, features)=(365,24,2)

๋์์ ๋ฐ์ดํฐ: (๋ฐฐ์น ํฌ๊ธฐ, ํ๋ ์์, ์ด๋ฏธ์ง ๋์ด, ์ด๋ฏธ์ง ๋๋น, ์ฑ๋์) ํ์์ 5์ฐจ์ ๋ํ์ด ํ
์์ ์ ์ฅ๋๋ค.(batch_size, frame, height, width, channels)=c(365,100,28,28,3)

์ผ๋ผ์ค๋ก ์ ๊ฒฝ๋ง์ ๊ตฌ์ถํ ๋ ํ์ํ ์์๋ค:
๋ชจ๋ธ: ํ๋์ ์ ๊ฒฝ๋ง์ ๋ํ๋ธ๋ค.๋ ์ด์ด: ์ ๊ฒฝ๋ง์์ ํ๋์ ์ธต์ด๋ค.์
๋ ฅ ๋ฐ์ดํฐ: ํ
์ํ๋ก์ฐ ํ
์ ํ์์ด๋ค.์์ค ํจ์: ์ ๊ฒฝ๋ง์ ์ถ๋ ฅ๊ณผ ์ ๋ต ๋ ์ด๋ธ ๊ฐ์ ์ฐจ์ด๋ฅผ ์ธก์ ํ๋ ํจ์์ด๋ค.์ตํฐ๋ง์ด์ : ํ์ต์ ์ํํ๋ ์ต์ ํ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ํ์ต๋ฅ ๊ณผ ๋ชจ๋ฉํ
์ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ๋ค์ผ๋ผ์ค์๋ ์ด๋ฐ ์์๋ค์ ๊ตฌํํ ์ฌ๋ฌ ํด๋์ค ์กด์ฌํ๋ค.

์
๋ ฅ์ ํธ๊ฐ ํ ๋ฐฉํฅ์ผ๋ก๋ง ์ ๋ฌ๋๋ ํผ๋ ํฌ์๋ ์ ๊ฒฝ๋ง์ ๊ตฌํํ๋ ๊ฐ์ฅ ๊ธฐ์ด์ ์ธ ์ ๊ฒฝ๋ง
โ
compile(optimizer, loss=None, metrics=None): ํ๋ จ์ ์ํด์ ๋ชจ๋ธ์ ๊ตฌ์ฑํ๋ ๋ฉ์๋
โ
fit(x=None, y=None, batch_size=None, epochs=1, verbose=1): ํ๋ จ ๋ฉ์๋
โ
evaluate(x=None, y=None): ํ
์คํธ ๋ชจ๋์์ ๋ชจ๋ธ์ ์์ค ํจ์ ๊ฐ๊ณผ ์ธก์ ํญ๋ชฉ ๊ฐ์ ๋ฐํ
โ
predict(x, batch_size=None): ์
๋ ฅ ์ํ์ ๋ํ ์์ธก๊ฐ์ ์์ฑ
โ
add(layer): ๋ ์ด์ด๋ฅผ ๋ชจ๋ธ์ ์ถ๊ฐ
โ
Input(shape, batch_size, name): ์
๋ ฅ์ ๋ฐ์์ ์ผ๋ผ์ค ํ
์๋ฅผ ์์ฑํ๋ ๊ฐ์ฒด
โ
Dense(units, activation=None, use_bias=True, input_shape): ์ ๋๋ค์ด ์ ๋ถ ์ฐ๊ฒฐ๋ ๋ ์ด์ด
โ
Embedding(input_dim, output_dim): ์์ฐ์ด ์ฒ๋ฆฌ์ ์ฒซ๋จ๊ณ์ ์ฌ์ฉ๋๋ ์๋ฒ ๋ฉ ๋ ์ด์ด
โ
MeanSquaredError: ์ ๋ต ๋ ์ด๋ธ๊ณผ ์์ธก๊ฐ ์ฌ์ด์ ํ๊ท ์ ๊ณฑ ์ค์ฐจ๋ฅผ ๊ณ์ฐํ๋ค. [โmseโ]
MeanSquaredError
(1st sample) 1 + 0 = 1
(2nd sample) 1 + 0 = 1
์ ์ฒด ํฉ = 1 + 1 = 2
์ ์ฒด ์์ ์ = 4
MSE = 2 / 4 = 0.5
โ
BinaryCrossentropy: ์ ๋ต ๋ ์ด๋ธ๊ณผ ์์ธก ๋ ์ด๋ธ ๊ฐ์ ๊ต์ฐจ ์ํธ๋กํผ ์์ค์ ๊ณ์ฐํ๋ค(์๋ฅผ ๋ค์ด์ ๊ฐ์์ง, ๊ฐ์์ง ์๋). [โbinary_crossentropyโ]
BinaryCrossentropy
(1) y=0, p=0.6 -> -log(0.4) โ 0.916
(2) y=1, p=0.4 -> -log(0.4) โ 0.916
(3) y=0, p=0.4 -> -log(0.6) โ 0.511
(4) y=0, p=0.6 -> -log(0.4) โ 0.916
์ดํฉ = 3.259 / 4 = 0.8149
import matplotlib.pyplot as plt
import tensorflow as tf; import numpy as np
y_true = [[0., 1.], [0., 0.]]
y_pred = [[1., 1.], [1., 0.]]
mse = tf.keras.losses.MeanSquaredError()
print(mse(y_true, y_pred).numpy()) # 0.5
y_true = [[0., 1.], [0., 0.]]
y_pred = [[0.6, 0.4], [0.4, 0.6]]
bce = tf.keras.losses.BinaryCrossentropy()
print(bce(y_true, y_pred).numpy()) # 0.8149245
โ
CategoricalCrossentropy: ์ ๋ต ๋ ์ด๋ธ๊ณผ ์์ธก ๋ ์ด๋ธ ๊ฐ์ ๊ต์ฐจ ์ํธ๋กํผ ์์ค์ ๊ณ์ฐํ๋ค(์๋ฅผ ๋ค์ด์ ๊ฐ์์ง, ๊ณ ์์ด, ํธ๋์ด). ์ ๋ต ๋ ์ด๋ธ์ ์ํซ ์ธ์ฝ๋ฉ์ผ๋ก ์ ๊ณต [โcategorical_crossentropyโ]
CategoricalCrossentropy
(1st sample) y = [0,1,0], p = [0.05, 0.95, 0]
--> -log(0.95) โ 0.051
(2nd sample) y = [0,0,1], p = [0.1, 0.8, 0.1]
--> -log(0.1) โ 2.302
์ดํฉ = 0.051 + 2.302 = 2.353 / 2 = 1.1769
โ
SparseCategoricalCrossentropy: ์ ๋ต ๋ ์ด๋ธ๊ณผ ์์ธก ๋ ์ด๋ธ ๊ฐ์ ๊ต์ฐจ ์ํธ๋กํผ ์์ค์ ๊ณ์ฐํ๋ค. (์๋ฅผ ๋ค์ด์ ๊ฐ์์ง, ๊ณ ์์ด, ํธ๋์ด)
์ ๋ต ๋ ์ด๋ธ์ ์ ์๋ก ์ ๊ณต [โsparse_categorical_crossentropyโ]
SparseCategoricalCrossentropy
(1st sample) y=1 โ p=0.95 โ -log(0.95) โ 0.051
(2nd sample) y=2 โ p=0.1 โ -log(0.1) โ 2.302
ํ๊ท = (0.051 + 2.302) / 2 = 1.1769
y_true = [[0, 1, 0], [0, 0, 1]] # ์-ํซ ํํ์ผ๋ก ๋ถ๋ฅ๋ฅผ ๋ํ๋ธ๋ค.
y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
cce = tf.keras.losses.CategoricalCrossentropy()
print(cce(y_true, y_pred).numpy()) # 1.1769392
y_true = np.array([1, 2]) # ์ ์๋ก ๋ถ๋ฅ๋ฅผ ๋ํ๋ธ๋ค.
y_pred = np.array([[0.05, 0.95, 0], [0.1, 0.8, 0.1]])
scce = tf.keras.losses.SparseCategoricalCrossentropy()
print(scce(y_true, y_pred).numpy()) # 1.1769392
Accuracy: ์ ํ๋์ด๋ค. ์์ธก๊ฐ์ด ์ ๋ต ๋ ์ด๋ธ๊ณผ ๊ฐ์ ํ์๋ฅผ ๊ณ์ฐํ๋ค.categorical_accuracy: ๋ฒ์ฃผํ ์ ํ๋์ด๋ค. ์ ๊ฒฝ๋ง์ ์์ธก๊ฐ์ด ์-ํซ ๋ ์ด๋ธ๊ณผ ์ผ์นํ๋ ๋น๋๋ฅผ ๊ณ์ฐํ๋ค.m = tf.keras.metrics.Accuracy()
m.update_state( [[1], [2], [3], [4]], [[0], [2], [3], [4]])
print(m.result().numpy()) # 0.75
m = tf.keras.metrics.CategoricalAccuracy()
m.update_state([[0, 0, 1], [0, 1, 0]], [[0.1, 0.9, 0.8], [0.05, 0.95, 0]])
print(m.result().numpy()) # 0.5
์์ค ํจ์๋ฅผ ๋ฏธ๋ถํ์ฌ์ ๊ฐ์ค์น๋ฅผ ๋ณ๊ฒฝํ๋ ๋ณ๊ฒฝํ๋ ๊ฐ์ฒด
SGD: ํ๋ฅ ์ ๊ฒฝ์ฌ ํ๊ฐ๋ฒ(Stochastic Gradient Descent, SGD), Nesterov ๋ชจ๋ฉํ
์ ์ง์, ์์ ์ ๊ฒฝ๋ง ์ ํฉopt = tf.keras.optimizers.SGD(learning_rate=0.1, momentum=0.9)
Adagrad: ๊ฐ๋ณ ํ์ต๋ฅ ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ, SGD๋ฅผ ์ง๋ณด์ํจ ์ต์ ํ ๋ฐฉ๋ฒAdadelta: ๋ชจ๋ฉํ
์ ์ด์ฉํ์ฌ ๊ฐ์ํ๋ ํ์ต๋ฅ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๋ Adagrad์ ๋ณํRMSprop: Adagrad์ ๋ํ ์์ ํAdam: ๊ธฐ๋ณธ์ ์ผ๋ก (RMSprop + ๋ชจ๋ฉํ
), ์ธ๊ธฐ์์sigmoidrelu(Rectified Linear Unit)softmaxtanhselu(Scaled Exponential Linear Unit)softplus
์ ๊ฒฝ๋ง์์ ํ์ต ์ ์ ์ฌ์ฉ์๊ฐ ์ง์ ์ค์ ํด์ผ ํ๋ ๊ฐ๋ค์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ผ๊ณ ํ๋ค.
์ด ๊ฐ๋ค์ ๋ชจ๋ธ์ ์ฑ๋ฅ๊ณผ ํ์ต ํจ์จ์ ํฐ ์ํฅ์ ๋ฏธ์น๋ค.
| ํ์ดํผํ๋ผ๋ฏธํฐ | ์ค๋ช |
|---|---|
| ์๋์ธต์ ๊ฐ์ | ์ค์ฐจ๊ฐ ๋ ์ด์ ๊ฐ์ ๋์ง ์์ ๋๊น์ง ๋ ์ด์ด๋ฅผ ์ถ๊ฐํ๋ค. |
| ์ ๋์ ๊ฐ์ | ์ ๋ ์๊ฐ ๋ง์์๋ก ํํ๋ ฅ์ด ์ข์์ง์ง๋ง ๊ณผ์ ํฉ์ ์ฃผ์ํด์ผ ํ๋ค. |
| ํ์ต๋ฅ (learning rate) | ๋๋ฌด ํฌ๋ฉด ๋ฐ์ฐํ๊ณ , ๋๋ฌด ์์ผ๋ฉด ํ์ต์ด ๋๋ฆฌ๋ค. ์ ์์ ํ์ต๋ฅ ์ด ํจ๊ณผ์ ์ด๋ค. |
| ๋ชจ๋ฉํ (momentum) | ์ง๋์ ๋ฐฉ์งํ์ฌ ์์ ์ ์ธ ํ์ต์ ๋์์ค๋ค. ๋ณดํต 0.5~0.9 ์ฌ์ด์ ๊ฐ์ ์ฌ์ฉํ๋ค. |
| ๋ฏธ๋ ๋ฐฐ์น ํฌ๊ธฐ | ์ผ๋ฐ์ ์ผ๋ก 32๋ฅผ ๊ธฐ๋ณธ์ผ๋ก, 64, 128, 256 ๋ฑ๋ ์ฌ์ฉ๋๋ค. |
| ์ํฌํฌ ์ (epochs) | ๊ฒ์ฆ ์ ํ๋๊ฐ ๊ฐ์ํ๊ธฐ ์์ํ ๋๊น์ง ๋ฐ๋ณตํ๋ค. |

๊ธฐ๋ณธ๊ฐ ์ฌ์ฉ
ํ๋ ์์ํฌ(์: Keras, sklearn)์์ ์ ๊ณตํ๋ ๊ธฐ๋ณธ๊ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค.
์๋ ๊ฒ์
์ฌ์ฉ์๊ฐ ์ง์ ๊ฐ์ ์ง์ ํ๋ฉด์ ๊ฒฝํ์ ์ผ๋ก ์กฐ์ ํ๋ค.
๊ทธ๋ฆฌ๋ ๊ฒ์ (Grid Search)
๊ฐ ํ์ดํผํ๋ผ๋ฏธํฐ์ ๋ํด ์ฌ๋ฌ ๊ฐ์ ํ๋ณด ๊ฐ์ ์ ํ๊ณ , ๋ชจ๋ ์กฐํฉ์ ์คํํ์ฌ ๊ฐ์ฅ ์ฑ๋ฅ์ด ์ข์ ์กฐํฉ์ ์ฐพ๋๋ค.
sklearn์ GridSearchCV๋ฅผ ํตํด ์์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.

๋๋ค ๊ฒ์ (Random Search)# ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ก๋
# !pip install scikeras
# !pip install scikit-learn==1.3.2
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from sklearn.model_selection import GridSearchCV
from scikeras.wrappers import KerasClassifier
# ๋ฐ์ดํฐ ์ธํธ ์ค๋น
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255
train_labels = tf.keras.utils.to_categorical(train_labels)
test_labels = tf.keras.utils.to_categorical(test_labels)
# ์ ๊ฒฝ๋ง ๋ชจ๋ธ ๊ตฌ์ถ
def build_model():
network = tf.keras.models.Sequential()
network.add(tf.keras.layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(tf.keras.layers.Dense(10, activation='sigmoid'))
network.compile(
optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy']
)
return network
# ํ์ดํผ ๋งค๊ฐ๋ณ์ ๋์
๋๋ฆฌ
param_grid = {
'epochs': [1, 2, 3], # ์ํฌํฌ ์: 1, 2, 3
'batch_size': [32, 64] # ๋ฐฐ์น ํฌ๊ธฐ: 32, 64
}
# ์ผ๋ผ์ค ๋ชจ๋ธ์ sklearn์์ ์ฌ์ฉํ๋๋ก ํฌ์ฅํ๋ค.
model = KerasClassifier(build_fn=build_model, verbose=1)
# ๊ทธ๋ฆฌ๋ ๊ฒ์
gs = GridSearchCV(
estimator=model,
param_grid=param_grid,
cv=3,
n_jobs=-1
)
# ๊ทธ๋ฆฌ๋ ๊ฒ์ ๊ฒฐ๊ณผ ์ถ๋ ฅ
grid_result = gs.fit(train_images, train_labels)
print(grid_result.best_score_)
print(grid_result.best_params_)
...
Epoch 3/3
938/938 [==============================] - 3s 4ms/step - loss: 0.0664 - accuracy: 0.9799
157/157 [==============================] - 0s 939us/step
0.968666672706604
{'batch_size': 64, 'epochs': 3}
์ผ๋ผ์ค๋ฅผ ํ์ฉํ ์ ๊ฒฝ๋ง ๋ชจ๋ธ ๊ตฌ์ฑ๊ณผ ํ์ดํผํ๋ผ๋ฏธํฐ
Sequential ๋ชจ๋ธ์ ์ผ๋ผ์ค์์ ๊ฐ์ฅ ๊ฐ๋จํ ์ ๊ฒฝ๋ง ๊ตฌ์ฑ ๋ฐฉ์์ด๋ฉฐ, Dense ๋ ์ด์ด๋ฅผ ํตํด ์์ ์ฐ๊ฒฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋ ๋ค.
ํ์ดํผํ๋ผ๋ฏธํฐ๋ ์๋์ธต ์, ์ ๋ ์, ํ์ต๋ฅ ๋ฑ ๋ชจ๋ธ ์ธ๋ถ์์ ๊ฐ๋ฐ์๊ฐ ์ค์ ํ๋ ๊ฐ์ด๋ฉฐ, ๊ทธ๋ฆฌ๋ ๊ฒ์ ๋ฑ์ ํตํด ์ต์ ๊ฐ์ ํ์ํ ์ ์๋ค.