#https://data-analysis-stats.jp/%E6%B7%B1%E5%B1%9E%E5%AD%A6%E7%BF%92/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A9%E3%83%AB%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%83%97%E3%83%AB%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%EF%BC%88pruning%E3%83%BB%E6%9E%9D/
#上記記事のコードを実行してみる
! pip install -q tensorflow-model-optimization
import tempfile
import os
import numpy as np
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
import random
import tensorflow as tf
from tensorflow import keras
from keras.datasets import mnist
result = {}
output_dir = ('/content/drive/MyDrive/DNN_user/model')
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Load MNIST dataset
mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 画像の表示
plt.rcParams['figure.figsize'] = (9,9) # Make the figures a bit bigger
for i in range(9):
plt.subplot(3,3,i+1)
num = random.randint(0, len(train_images))
plt.imshow(train_images[num], cmap='gray', interpolation='none')
plt.title("Class {}".format(train_labels[num]))
plt.tight_layout()
# 正規化
train_images = train_images / 255.0
test_images = test_images / 255.0
# MNIST without pruning
start_time = datetime.now()
# モデル構成
model = keras.Sequential([
keras.layers.InputLayer(input_shape=(28, 28)),
keras.layers.Reshape(target_shape=(28, 28, 1)),
keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation=tf.nn.relu),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(10)
])
# モデル設定
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
# モデル学習
model.fit(train_images, train_labels, epochs=4, validation_split=0.1)
# 結果
result[('1. NN no pruning', 'fit_time')] = datetime.now() - start_time
# モデル保存
model_path = (output_dir+'model1.h5')
tf.keras.models.save_model(model, model_path, include_optimizer=False)
# 検証
_, baseline_model_accuracy = model.evaluate(test_images, test_labels, verbose=0)
result[('1. NN no pruning', 'accuracy')] = baseline_model_accuracy
result[('1. NN no pruning', 'file_size_KB')] = int(os.path.getsize(model_path)/ 1024)
# 結果表示
result_df = pd.Series(result).unstack().reindex(columns=['accuracy', 'fit_time', 'file_size_KB'])
result_df
import tensorflow_model_optimization as tfmot
start_time = datetime.now()
prune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude
# 4 エポックでプルーニングモデルを作成
batch_size = 128
epochs = 4
validation_split = 0.1
num_images = train_images.shape[0] * (1 - validation_split)
end_step = np.ceil(num_images / batch_size).astype(np.int32) * epochs
# プルーニングの設定
pruning_params = {'pruning_schedule': tfmot.sparsity.keras.PolynomialDecay(initial_sparsity=0.50, final_sparsity=0.80, begin_step=0, end_step=end_step)}
model_for_pruning = prune_low_magnitude(model, **pruning_params)
# コンパイル
model_for_pruning.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model_for_pruning.summary()
logdir = tempfile.mkdtemp()
callbacks = [
tfmot.sparsity.keras.UpdatePruningStep(),
tfmot.sparsity.keras.PruningSummaries(log_dir=logdir),
]
# モデル学習
model_for_pruning.fit(train_images, train_labels,
batch_size=batch_size, epochs=epochs, validation_split=validation_split,
callbacks=callbacks)
# 結果
result[('2. NN with pruning', 'fit_time')] = datetime.now() - start_time
# モデル保存
model_path = ('temp/model2.h5')
tf.keras.models.save_model(model_for_pruning, model_path, include_optimizer=False)
# 検証
_, model_for_pruning_accuracy = model_for_pruning.evaluate(test_images, test_labels, verbose=0)
result[('2. NN with pruning', 'accuracy')] = model_for_pruning_accuracy
result[('2. NN with pruning', 'file_size_KB')] = int(os.path.getsize(model_path)/ 1024)
# 結果表示
result_df = pd.Series(result).unstack().reindex(columns=['accuracy', 'fit_time', 'file_size_KB'])
result_df