トレーニングにまつわるあれこれを掲載しているブログではありますが,都合によりこのような記事を掲載いたします.
現在一般社団法人ディープラーニング協会のE資格を取得するため,ラビットチャレンジなるプログラムを受講しています.本プログラムにおいてレポート公開が必須になっていることから,こちらのブログにてレポートします.
コード演習
RNN
バイナリ加算をRNNで実施してみる.
import numpy as np from common import functions import matplotlib.pyplot as plt # def d_tanh(x): # データを用意 # 2進数の桁数 binary_dim = 8 # 最大値 + 1 largest_number = pow(2, binary_dim) # largest_numberまで2進数を用意 binary = np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1) input_layer_size = 2 hidden_layer_size = 16 output_layer_size = 1 weight_init_std = 1 learning_rate = 0.1 iters_num = 10000 plot_interval = 100 # ウェイト初期化 (バイアスは簡単のため省略) # W_in = weight_init_std * np.random.randn(input_layer_size, hidden_layer_size) # W_out = weight_init_std * np.random.randn(hidden_layer_size, output_layer_size) # W = weight_init_std * np.random.randn(hidden_layer_size, hidden_layer_size) # Xavier W_in = np.random.randn(input_layer_size, hidden_layer_size) / (np.sqrt(input_layer_size)) W_out = np.random.randn(hidden_layer_size, output_layer_size) / (np.sqrt(hidden_layer_size)) W = np.random.randn(hidden_layer_size, hidden_layer_size) / (np.sqrt(hidden_layer_size)) # He # 勾配 W_in_grad = np.zeros_like(W_in) W_out_grad = np.zeros_like(W_out) W_grad = np.zeros_like(W) u = np.zeros((hidden_layer_size, binary_dim + 1)) z = np.zeros((hidden_layer_size, binary_dim + 1)) y = np.zeros((output_layer_size, binary_dim)) delta_out = np.zeros((output_layer_size, binary_dim)) delta = np.zeros((hidden_layer_size, binary_dim + 1)) all_losses = [] for i in range(iters_num): # A, B初期化 (a + b = d) a_int = np.random.randint(largest_number/2) a_bin = binary[a_int] # binary encoding b_int = np.random.randint(largest_number/2) b_bin = binary[b_int] # binary encoding # 正解データ d_int = a_int + b_int d_bin = binary[d_int] # 出力バイナリ out_bin = np.zeros_like(d_bin) # 時系列全体の誤差 all_loss = 0 # 時系列ループ for t in range(binary_dim): # 入力値 X = np.array([a_bin[ - t - 1], b_bin[ - t - 1]]).reshape(1, -1) # 時刻tにおける正解データ dd = np.array([d_bin[binary_dim - t - 1]]) u[:,t+1] = np.dot(X, W_in) + np.dot(z[:,t].reshape(1, -1), W) z[:,t+1] = functions.sigmoid(u[:,t+1]) y[:,t] = functions.sigmoid(np.dot(z[:,t+1].reshape(1, -1), W_out)) #誤差 loss = functions.mean_squared_error(dd, y[:,t]) delta_out[:,t] = functions.d_mean_squared_error(dd, y[:,t]) * functions.d_sigmoid(y[:,t]) all_loss += loss out_bin[binary_dim - t - 1] = np.round(y[:,t]) for t in range(binary_dim)[::-1]: X = np.array([a_bin[-t-1],b_bin[-t-1]]).reshape(1, -1) delta[:,t] = (np.dot(delta[:,t+1].T, W.T) + np.dot(delta_out[:,t].T, W_out.T)) * functions.d_sigmoid(u[:,t+1]) # 勾配更新 W_out_grad += np.dot(z[:,t+1].reshape(-1,1), delta_out[:,t].reshape(-1,1)) W_grad += np.dot(z[:,t].reshape(-1,1), delta[:,t].reshape(1,-1)) W_in_grad += np.dot(X.T, delta[:,t].reshape(1,-1)) # 勾配適用 W_in -= learning_rate * W_in_grad W_out -= learning_rate * W_out_grad W -= learning_rate * W_grad W_in_grad *= 0 W_out_grad *= 0 W_grad *= 0 if(i % plot_interval == 0): all_losses.append(all_loss) print("iters:" + str(i)) print("Loss:" + str(all_loss)) print("Pred:" + str(out_bin)) print("True:" + str(d_bin)) out_int = 0 for index,x in enumerate(reversed(out_bin)): out_int += x * pow(2, index) print(str(a_int) + " + " + str(b_int) + " = " + str(out_int)) print("------------") lists = range(0, iters_num, plot_interval) plt.plot(lists, all_losses, label="loss") plt.show()
学習の状況は以下.
具体的にはこんな感じ.
iters:0 Loss:0.9947875225909557 Pred:[1 1 1 1 0 1 1 0] True:[1 1 0 1 1 1 0 1] 114 + 107 = 246 ------------ iters:100 Loss:0.8590871185218547 Pred:[0 0 0 0 0 0 0 0] True:[0 1 0 0 1 0 0 0] 32 + 40 = 0 ↓ iters:9900 Loss:0.002582312425123265 Pred:[1 1 1 0 0 0 0 1] True:[1 1 1 0 0 0 0 1] 109 + 116 = 225
CNN
こちらも実施.どうも受領した資料tensorflowのバージョンが1.x系の箇所があるのか,そのままでは回らない. tf.kerasに直して回した.
import tensorflow as tf # logging levelを変更 # tf.logging.set_verbosity(tf.logging.ERROR) # 必要なライブラリのインポート import keras import matplotlib.pyplot as plt from data.mnist import load_mnist (x_train, d_train), (x_test, d_test) = load_mnist(normalize=True, one_hot_label=True) # 行列として入力するための加工 batch_size = 128 num_classes = 10 epochs = 20 img_rows, img_cols = 28, 28 x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) # 必要なライブラリのインポート、最適化手法はAdamを使う from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, Flatten from tensorflow.keras.layers import Conv2D, MaxPooling2D from tensorflow.keras.optimizers import Adam model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape)) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(num_classes, activation='softmax')) model.summary() # バッチサイズ、エポック数 batch_size = 128 epochs = 20 model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy']) history = model.fit(x_train, d_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, d_test)) #Accuracy plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('model accuracy') plt.ylabel('accuracy') plt.xlabel('epoch') plt.legend(['train', 'test'], loc='upper left') # plt.ylim(0, 1.0) plt.show()
出力は以下.
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 26, 26, 32) 320 conv2d_1 (Conv2D) (None, 24, 24, 64) 18496 max_pooling2d (MaxPooling2D (None, 12, 12, 64) 0 ) dropout (Dropout) (None, 12, 12, 64) 0 flatten (Flatten) (None, 9216) 0 dense (Dense) (None, 128) 1179776 dropout_1 (Dropout) (None, 128) 0 dense_1 (Dense) (None, 10) 1290 ================================================================= Total params: 1,199,882 Trainable params: 1,199,882 Non-trainable params: 0 _________________________________________________________________ Epoch 1/20 469/469 [==============================] - 22s 21ms/step - loss: 0.2414 - accuracy: 0.9261 - val_loss: 0.0493 - val_accuracy: 0.9843 Epoch 2/20 469/469 [==============================] - 9s 20ms/step - loss: 0.0832 - accuracy: 0.9751 - val_loss: 0.0359 - val_accuracy: 0.9886 Epoch 3/20 469/469 [==============================] - 9s 20ms/step - loss: 0.0620 - accuracy: 0.9814 - val_loss: 0.0280 - val_accuracy: 0.9898 ... Epoch 20/20 469/469 [==============================] - 9s 20ms/step - loss: 0.0137 - accuracy: 0.9956 - val_loss: 0.0292 - val_accuracy: 0.9918