機械学習プログラミング

科目名: メディアネットワーク演習II(2020年~)
対象: メディアネットワークコース3年目
日時: 5月25日(月)8:45~10:15
場所: M棟1階計算機室
レポート提出締切: 6月1日(月)13:00
レポート提出先: メールにファイルを添付し、aoki@ime.ist.hokudai.ac.jpまで提出すること.
連絡先: 青木 直史(情報エレクトロニクス棟6階6-07)(Tel: 011-706-6532)(E-mail: aoki@ime.ist.hokudai.ac.jp)

目的

 本演習は,Pythonによるプログラミングを通して,機械学習プログラミングに対する理解を深めることを目的としている.

1.はじめに

 本演習は,Jupyter Notebookを利用し,下記のプログラムをブラウザを使って実行しながら進めるものとする.環境のインストールはつぎの手順のとおり.
(1) Anacondaのインストール
https://www.anaconda.com/distribution/
から「Python 3.7」のインストーラをダウンロードして実行.
(2) ライブラリのインストール
Anaconda Promptを開く.
pip install librosa
と入力して実行.
pip install --upgrade tensorflow==2.0.0
と入力して実行.
pip install keras
と入力して実行.
(3) Jupyter Notebookの起動
jupyter notebook
と入力して実行.
(4) ブラウザ(Chrome推奨)を利用してプログラミングを行う.
「New」ボタンをクリックして「Python3」を選択.
音ファイルや画像ファイルを利用するときは「Upload」ボタンをクリックし,必要なファイルをJupyter Notebookにアップロードすること.

2.手書き文字の認識

 つぎのプログラムを実行し,ニューラルネットワークを利用して手書き文字を認識する一連の手順を確かめなさい.
(1)
%matplotlib inline
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam
import matplotlib.pyplot as plt
(2)
(x_trains, y_trains), (x_tests, y_tests) = mnist.load_data()
(3)
plt.figure(1, figsize=(12, 3.2))
plt.subplots_adjust(wspace = 0.5)
plt.gray()
(4)
for id in range(3):
    plt.subplot(1, 3, id + 1)
    img = x_trains[id, :, :].reshape(28, 28)
    plt.pcolor(255 - img)
    plt.text(24, 26, "%d" % y_trains[id], color = 'blue', fontsize = 20)
    plt.xlim(0, 27)
    plt.ylim(27, 0)
(5)
x_trains = x_trains.reshape(60000, 784)
x_trains = x_trains / 255
y_trains = np_utils.to_categorical(y_trains, 10)

x_tests = x_tests.reshape(10000, 784)
x_tests = x_tests / 255
y_tests = np_utils.to_categorical(y_tests, 10)
(6)
model = Sequential()
model.add(Dense(200, input_dim = 784, activation = 'sigmoid'))
model.add(Dense(10, activation = 'softmax'))
model.compile(loss = 'categorical_crossentropy', optimizer = Adam(), metrics = ['accuracy'])
model.summary()
(7)
history = model.fit(x_trains, y_trains, epochs = 10, batch_size = 100, verbose = 1, validation_data = (x_tests, y_tests))
(8)
plt.figure(figsize = (15, 6))
plt.subplots_adjust(wspace = 0.2)

plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label = 'training', color = 'black')
plt.plot(history.history['val_loss'], label = 'test', color = 'red')
plt.ylim(0, 1)
plt.legend()
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')

plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label = 'training', color = 'black')
plt.plot(history.history['val_accuracy'], label = 'test', color = 'red')
plt.ylim(0.5, 1)
plt.legend()
plt.grid()
plt.xlabel('epoch')
plt.ylabel('accuracy')
(9)
with open('model.json', 'w') as json_file:
    json_file.write(model.to_json())
model.save_weights('weight.h5')
(10)
from keras.models import model_from_json
from keras.optimizers import Adam
import imageio
import numpy as np
import matplotlib.pyplot as plt
(11)
model = model_from_json(open('model.json', 'r').read())
model.load_weights('weight.h5')
model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
(12)
width = 28
height = 28
pixels = width * height
(13)
img = imageio.imread('4.png')[:, :, 0]
(14)
img_flat = np.array(img).reshape(1, pixels)
img_flip = np.full((1, pixels), 255) - img_flat
img_norm = img_flip / 255
(15)
plt.figure(1, figsize=(5, 5))
plt.gray()
img_flat = np.array(img).reshape(28, 28)
plt.pcolor(255 - img_flat)
plt.xlim(0, 27)
plt.ylim(27, 0)
(16)
prediction = model.predict(img_norm, batch_size = 100, verbose = 1)
print("この数字は{0}です。".format(np.argmax(prediction)))

3.画像のノイズ除去

 つぎのプログラムを実行し,ニューラルネットワークを利用して画像のノイズ除去を行う一連の手順を確かめなさい.
(1)
%matplotlib inline
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
from IPython.display import display_png
from keras.preprocessing.image import array_to_img
(2)
def unet(input_size):
        
    conv1 = tf.keras.layers.Conv2D(16, 5, strides = (2, 2), padding = 'same')(input_size)
    conv1 = tf.keras.layers.BatchNormalization()(conv1)   
    conv1 = tf.keras.layers.LeakyReLU(alpha = 0.2)(conv1)
    
    conv2 = tf.keras.layers.Conv2D(32, 5, strides = (2, 2), padding='same')(conv1)
    conv2 = tf.keras.layers.BatchNormalization()(conv2)
    conv2 = tf.keras.layers.LeakyReLU(alpha = 0.2)(conv2)
    
    deconv3 = tf.keras.layers.Conv2DTranspose(16, 5, strides = 2, padding = 'same')(conv2)
    deconv3 = tf.keras.layers.BatchNormalization()(deconv3)
    deconv3 = tf.keras.layers.Dropout(0.5)(deconv3)
    deconv3 = tf.keras.layers.Activation('relu')(deconv3)
    
    deconv4 = tf.keras.layers.Conv2DTranspose(1, 5, strides = (2, 2), padding = 'same')(deconv3)
    deconv4 = tf.keras.layers.BatchNormalization()(deconv4)
    deconv4 = tf.keras.layers.Dropout(0.5)(deconv4)
    deconv4 = tf.keras.layers.Activation('relu')(deconv4)
    
    Umodel = tf.keras.Model(inputs = input_size, outputs = deconv4)
    
    return Umodel
(3)
def add_noise(data):
    for i in range(len(data)):
        data[i] *= 0.3 * np.random.rand(28, 28)
        data[i] += 100 * np.random.rand(28, 28)
    
    return data
(4)
mnist = tf.keras.datasets.mnist

(x_trains, y_trains), (x_tests, y_tests) = mnist.load_data()

x_trains_noise = add_noise(x_trains.astype('float16'))
x_tests_noise  = add_noise(x_tests.astype('float16'))

x_trains, x_tests = x_trains.reshape(-1, 28, 28, 1) / 255.0, x_tests.reshape(-1, 28, 28, 1) / 255.0
x_trains_noise, x_tests_noise = x_trains_noise.reshape(-1, 28, 28, 1) / 255.0, x_tests_noise.reshape(-1, 28, 28, 1) / 255.0

print("\n-------------------------------data shape-------------------------------------",
      "\ntrain data shape:",x_trains_noise.shape,"\ttrain label shape:",x_trains.shape,
      "\ntest data shape :",x_tests_noise.shape,"\ttest  label shape:",x_tests.shape,
      "\n-------------------------------data show-------------------------------------\nex)train data")
(5)
display_png(array_to_img(x_trains_noise[0]))
display_png(array_to_img(x_trains[0]))
print("\nex)test data")
display_png(array_to_img(x_tests_noise[0]))
display_png(array_to_img(x_tests[0]))
(6)
input_size  = tf.keras.Input((28, 28, 1))
model = unet(input_size)
model.compile(optimizer = 'adam', loss = 'mean_absolute_error', metrics = ['accuracy'])
(7)
inputsize  = tf.keras.Input((28, 28, 1))
model = unet(inputsize)
model.compile(optimizer = 'adam', loss = 'mean_absolute_error', metrics = ['accuracy'])
(8)
history = model.fit(x_trains_noise,x_trains, epochs = 10, batch_size = 100, shuffle = True, validation_split = 0.1)
(9)
pred_data = model.predict(x_tests_noise, batch_size = 100)
(10)
for i in range(10):
    print("\ntest data [No"+str(i)+"]\n<Mnist data>")
    display_png(array_to_img(x_tests[i]))
    print("<with Noise data>")
    display_png(array_to_img(x_tests_noise[i]))
    print("<predict data>")
    display_png(array_to_img(pred_data[i]))

4.レポートについて

 下記の課題に挑戦し,レポートを作成しなさい.
(課題1) ふたつのプログラムを解読し,どのような処理を行っているのか,具体的に説明しなさい.
(課題2) 処理の性能をさらに向上させるにはどうしたらよいか,プログラムの改良を試みなさい.

参考文献

チームカルポ, ``ディープラーニングの理論と実装,'' 秀和システム, 2018.

Last Modified: May 13 12:00 JST 2020 by Naofumi Aoki
E-mail: aoki@ime.ist.hokudai.ac.jp