1週間ほど前にM1のMacbook Airを購入しました。
試しにMNISTで機械学習をやってみたので、やり方と結果のメモです。
MNISTは0〜9の手書き文字の画像がセットになっており、画像認識で数字をAIが数字を当てるものになっています。
環境構築
macOS VenturaからPythonの同梱が終了されたようなので1からPythonをインストールします。
私の場合homebrewからインストールするとパスがうまく通せなかったので公式サイトからインストールしました。
今回はPython 3.9.13にしました。
Pythonをインストールしたら次はライブラリをインストールします。
以下をpipで以下をインストールしましょう。
pipのアップグレード
pip3 install --upgrade pip
Numpy
pip3 install numpy
pandas
pip3 install pandas
Tensorflow
pip3 install tensorflow-macos
matplotlib
pip3 install matplotlib
MNISTの実行
何故かKerasを使ってmnistをインストールしようとするとエラーしたので、事前にダウンロードしてローカルで実行することにします。
MNISTのデータセットは以下のホームページで公開されています。
https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
mnist.npzがダウンロードされるので、/Username/.keras/datasetsにコピーします。
次に実行のためのプログラムですが、以下のように記述します。
今回は3層のディープラーニングを行います。
import os
import pathlib
import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import time
def main():
start = time.time()
CSV_FILE_PATH = "trainlog.csv"
if not os.path.exists(CSV_FILE_PATH):
pathlib.Path(CSV_FILE_PATH).touch()
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
del mnist
x_train, x_test = x_train/255.0, x_test/255.0
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape = (28, 28), name = 'input'),
tf.keras.layers.Dense(512, name = 'fc_1'),
tf.keras.layers.Activation(tf.nn.relu, name = 'relu_1'),
tf.keras.layers.Dense(256, name = 'fc_2'),
tf.keras.layers.Activation(tf.nn.relu, name = 'relu_2'),
tf.keras.layers.Dense(256, name = 'fc_3'),
tf.keras.layers.Activation(tf.nn.relu, name = 'relu_3'),
tf.keras.layers.Dense(10, name = 'dense_3'),
tf.keras.layers.Activation(tf.nn.softmax, name = 'softmax')])
model.summary()
model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy', metrics = ['accuracy'])
callbacks = []
callbacks.append(tf.keras.callbacks.CSVLogger(CSV_FILE_PATH))
history = model.fit(x_train, y_train, batch_size = 100, epochs = 20, verbose = 1, validation_data = (x_test, y_test), callbacks = callbacks)
train_loss, train_acc = model.evaluate(x_train, y_train, verbose = 1)
print("loss(train): {:.4}".format(train_loss))
print("accuracy(train): {:.4}".format(train_acc))
test_loss, test_acc = model.evaluate(x_test, y_test, verbose = 1)
print("loss(test): {:.4}".format(test_loss))
print("accuracy(test): {:.4}".format(test_acc))
df = pd.read_csv(CSV_FILE_PATH)
df.head()
print(time.time() - start)
epochs = df["epoch"].values
train_acc = df["accuracy"].values
train_loss = df["loss"].values
test_acc = df["val_accuracy"].values
test_loss = df["val_loss"].values
plt.plot(epochs, train_loss, label = 'train data')
plt.plot(epochs, test_loss, label = 'test data')
plt.xlabel("epochs")
plt.ylabel("loss\n(categorical crossentropy)")
plt.legend(loc = "upper right")
plt.show()
plt.plot(epochs, train_acc, label = 'train data')
plt.plot(epochs, test_acc, label = 'test data')
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.legend(loc = "lower right")
plt.show()
fig = plt.figure(figsize = (12, 8))
ROW = 4
COLUMN = 5
for i in range(ROW * COLUMN):
y_true = y_test[i]
y_pred = model.predict(x_test[i].reshape(1, 28, 28))[0]
plt.subplot(ROW, COLUMN, i + 1)
plt.imshow(x_test[i], cmap = 'gray')
plt.title("No.{}\ny_true: {}, y_pred: {}".format(i, y_true, y_pred))
plt.axis("off")
fig.tight_layout()
fig.show()
if __name__ == '__main__': main()
実行結果
実行結果は以下のようになりました。ちゃんと学習できていることがわかります。
学習の実行速度は41秒でした。
他の記事を見ると、M1 Macbook proで100秒以上かかるようです。
それに比べれば格段に早くなったようです。
今回の結果はGeForce RTX 3070 Tiと同程度のようです。
M1が出てすぐはまだTensorflowへの対応ができていなかったことが影響しているのでしょう。
M1 Macbook Airでもそれなりに機械学習ができるようになったようです。
次はもう少し負荷のかかる学習で試してみたいと思います。