Magicode logo
Magicode
1

M1UltraでTensorFlow-macosを使って機械学習をやってみた

3月9日に注文したMac studioが4月25日にようやく届きました。
M1Ultraについて動画等で色々と報告が上がっていますが機械学習関連については見当たらなかったので、開発環境を構築しつつご紹介できればと思います。

環境:
M1Ultra 20コアCPU 64コアGPU ユニファイドメモリ128GB
macOS Monterey 12.3.1

はじめに

まずは以下の記事を参考にMiniforge等のインストールを実行しました。

M1 Mac環境構築ベストプラクティス

1.仮想環境の作成

ここから以下の手順に従ってtensorflow-macosがインストール可能か試したいと思います。
ターミナルを起動して以下を実行
conda create --name 仮想環境名 python=3.8
作成した仮想環境をアクティベート
conda activate 仮想環境名 

2.各種ライブラリのインストール

まずはTensorFlow-deps(依存パッケージ)を以下のコマンドでインストール
conda install -c apple tensorflow-deps 
続いてtensorflow-macosを以下のコマンドでインストール
python -m pip install tensorflow-macos
次にtensorflow-metalを以下のコマンドでインストール
python -m pip install tensorflow-metal
ついでにオプションのようですが、tensorflow-datasetsを以下のコマンドでインストール
python -m pip install tensorflow-datasets
あとは基本的なライブラリを以下のコマンドでインストール
conda install jupyter pandas numpy matplotlib scikit-learn
とりあえず、環境の構築はここまでにしておきます。

3.動作確認

正常にインストールできているか以下のプログラムで確認してみます。
import numpy as np
import pandas as pd
import sklearn
import tensorflow as tf
import matplotlib.pyplot as plt

# Check for TensorFlow GPU access
print(f"TensorFlow has access to the following devices:\n{tf.config.list_physical_devices()}")

# See TensorFlow version
print(f"TensorFlow version: {tf.__version__}")
こんな感じで表示されました。
TensorFlow has access to the following devices:
[PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU'), PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
TensorFlow version: 2.8.0

4.機械学習を試してみる

こちらの記事で紹介されている機械学習の動作確認プログラムを試してみたいと思います。

M1MAX MacBook Proで深層学習

import tensorflow as tf
import numpy as np
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.metrics import SparseCategoricalAccuracy
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications import VGG16 # Pre-trained VGG16 model

CIFAR10 = tf.keras.datasets.cifar10 # Use CIFAR10 dataset
(x_train, y_train), (x_valid, y_valid) = CIFAR10.load_data()
y_train = np.squeeze(y_train) # reduce demension
y_valid = np.squeeze(y_valid)

# data conversion 
def convert_data(x, y):
    x = tf.cast(x, tf.float32) # float32
    x /= 255. # pixcel normalization 
    return x, tf.cast(y, tf.int32)

train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)) 
valid_ds = tf.data.Dataset.from_tensor_slices((x_valid, y_valid)) 
AUTOTUNE = tf.data.experimental.AUTOTUNE 
train_ds = train_ds.shuffle(len(x_train)) 
train_ds = train_ds.repeat(1) 
train_ds = train_ds.batch(50) 
train_ds = train_ds.map(lambda x, y: tf.py_function(convert_data, [x, y], Tout=[tf.float32, tf.int32])) 
train_ds = train_ds.prefetch(buffer_size=AUTOTUNE) 
valid_ds = valid_ds.batch(50)
valid_ds = valid_ds.map(lambda x, y: tf.py_function(convert_data, [x, y], Tout=[tf.float32, tf.int32]))

# Pre-Trained VGG16
vgg16 = VGG16(include_top=False, weights='imagenet', input_shape=(32, 32, 3), pooling='avg')
h = Dropout(0.3)(vgg16.output)
h = Dense(256, activation='relu', name='dense01')(h) 
output = Dense(10, activation='softmax', name='output1')(h) 
vgg16.trainable = True 
model = Model(inputs=vgg16.input, outputs=output) 
model.summary()

model.compile(optimizer=Adam(0.0001), loss='sparse_categorical_crossentropy', metrics=SparseCategoricalAccuracy())   
with tf.device('/device:GPU:0'):
    model.fit(train_ds, epochs=10, validation_data=valid_ds, use_multiprocessing=True)
結果は以下となりました。
Output exceeds the size limit. Open the full output data in a text editor
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_2 (InputLayer)        [(None, 32, 32, 3)]       0         
                                                                 
 block1_conv1 (Conv2D)       (None, 32, 32, 64)        1792      
                                                                 
 block1_conv2 (Conv2D)       (None, 32, 32, 64)        36928     
                                                                 
 block1_pool (MaxPooling2D)  (None, 16, 16, 64)        0         
                                                                 
 block2_conv1 (Conv2D)       (None, 16, 16, 128)       73856     
                                                                 
 block2_conv2 (Conv2D)       (None, 16, 16, 128)       147584    
                                                                 
 block2_pool (MaxPooling2D)  (None, 8, 8, 128)         0         
                                                                 
 block3_conv1 (Conv2D)       (None, 8, 8, 256)         295168    
                                                                 
 block3_conv2 (Conv2D)       (None, 8, 8, 256)         590080    
                                                                 
 block3_conv3 (Conv2D)       (None, 8, 8, 256)         590080    
                                                                 
 block3_pool (MaxPooling2D)  (None, 4, 4, 256)         0         
...
Trainable params: 14,848,586
Non-trainable params: 0
_________________________________________________________________
Epoch 1/10
2022-04-26 21:10:05.366010: W tensorflow/core/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz
2022-04-26 21:10:05.840591: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
1000/1000 [==============================] - ETA: 0s - loss: 0.8688 - sparse_categorical_accuracy: 0.70302022-04-26 21:10:41.560972: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
1000/1000 [==============================] - 39s 35ms/step - loss: 0.8688 - sparse_categorical_accuracy: 0.7030 - val_loss: 0.5774 - val_sparse_categorical_accuracy: 0.8023
Epoch 2/10
1000/1000 [==============================] - 36s 36ms/step - loss: 0.5044 - sparse_categorical_accuracy: 0.8300 - val_loss: 0.5160 - val_sparse_categorical_accuracy: 0.8297
Epoch 3/10
1000/1000 [==============================] - 35s 35ms/step - loss: 0.3609 - sparse_categorical_accuracy: 0.8788 - val_loss: 0.4974 - val_sparse_categorical_accuracy: 0.8334
Epoch 4/10
1000/1000 [==============================] - 35s 35ms/step - loss: 0.2522 - sparse_categorical_accuracy: 0.9150 - val_loss: 0.4778 - val_sparse_categorical_accuracy: 0.8518
Epoch 5/10
1000/1000 [==============================] - 35s 35ms/step - loss: 0.1838 - sparse_categorical_accuracy: 0.9386 - val_loss: 0.5263 - val_sparse_categorical_accuracy: 0.8462
Epoch 6/10
1000/1000 [==============================] - 35s 35ms/step - loss: 0.1283 - sparse_categorical_accuracy: 0.9571 - val_loss: 0.5157 - val_sparse_categorical_accuracy: 0.8539
Epoch 7/10
1000/1000 [==============================] - 35s 35ms/step - loss: 0.1060 - sparse_categorical_accuracy: 0.9647 - val_loss: 0.5703 - val_sparse_categorical_accuracy: 0.8512
Epoch 8/10
1000/1000 [==============================] - 36s 36ms/step - loss: 0.0797 - sparse_categorical_accuracy: 0.9744 - val_loss: 0.5972 - val_sparse_categorical_accuracy: 0.8551
Epoch 9/10
1000/1000 [==============================] - 35s 35ms/step - loss: 0.0741 - sparse_categorical_accuracy: 0.9756 - val_loss: 0.6157 - val_sparse_categorical_accuracy: 0.8494
Epoch 10/10
1000/1000 [==============================] - 36s 36ms/step - loss: 0.0576 - sparse_categorical_accuracy: 0.9804 - val_loss: 0.7143 - val_sparse_categorical_accuracy: 0.8506
処理を動かしている間は以下のような状況でした。  

CPUの履歴   

GPUの履歴  

CPUは効率性のコア4つとパフォーマンスがちょっと動いているくらいであとはほとんど休んでますね。
GPUのほうは十分動いているので、とりあえず機械学習で使用できていそうです。

次回

これまでの方法で問題なく機械学習のライブラリをインストールできるようです。
せっかくなので、次回は他のMacと処理速度を比較してみたいと思います。

Discussion

コメントにはログインが必要です。