20210414のTensorFlowに関する記事は2件です。

黙々とMNISTを見るPython(MLP)

import tensorflow as tf tf.__version__ '2.5.0-rc1' 以下、黙々とMNISTのデータセットを使ってMLP(マルチ・レベル・パーセプトロン)をやっていきます。 このデータセットは0から9の10種類の数字の手書きの画像が入っています。 予測の難しい数字、正解(ラベル)が9で予測値が4などの出現数などを見ていくのがゴールです。 準備と前処理 import numpy as np from tensorflow.keras.datasets import mnist import matplotlib.pyplot as plt np.random.seed(42) (x_train, y_train), (x_test,y_test) = mnist.load_data() 含まれているラベルの数を数えてみると、各数字の画像の枚数は均等ではないようです。 unique, counts = np.unique(y_train, return_counts=True) print('Train labels:', dict(zip(unique,counts))) Train labels: {0: 5923, 1: 6742, 2: 5958, 3: 6131, 4: 5842, 5: 5421, 6: 5918, 7: 6265, 8: 5851, 9: 5949} unique, counts = np.unique(y_test, return_counts=True) print('Test labels:', dict(zip(unique,counts))) Test labels: {0: 980, 1: 1135, 2: 1032, 3: 1010, 4: 982, 5: 892, 6: 958, 7: 1028, 8: 974, 9: 1009} ランダムな25個の画像を表示。 indexes = np.random.randint(0, x_train.shape[0],size=25) indexes array([56422, 15795, 860, 38158, 54343, 44732, 11284, 54886, 6265, 16850, 37194, 21962, 47191, 44131, 16023, 41090, 1685, 769, 59735, 56101, 2433, 5311, 37819, 39188, 17568]) images = x_train[indexes] labels = y_train[indexes] plt.figure(figsize=(5,7)) for i in range(25): plt.subplot(5,5,i+1) plt.title(labels[i]) plt.imshow(images[i],cmap='gray') plt.axis('off') plt.show() すでにだいぶ読みづらいのが混ざっているねぇ。 import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Activation, Dropout from tensorflow.keras.utils import to_categorical, plot_model from tensorflow.keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() y_train array([5, 0, 4, ..., 5, 6, 8], dtype=uint8) y_test array([7, 2, 1, ..., 4, 5, 6], dtype=uint8) num_labels = len(np.unique(y_train)) num_labels 10 len(set(y_train)) 10 ラベルYを2進数表記にする(one-hot vector) y_train = to_categorical(y_train) y_train array([[0., 0., 0., ..., 0., 0., 0.], [1., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 1., 0.]], dtype=float32) y_test = to_categorical(y_test) y_test array([[0., 0., 0., ..., 1., 0., 0.], [0., 0., 1., ..., 0., 0., 0.], [0., 1., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32) データXを0から1のfloatにする (normalization) image_size = x_train.shape[1] image_size 28 input_size = image_size * image_size input_size 784 x_train = np.reshape(x_train, [-1, input_size]) x_train array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], dtype=uint8) x_train = x_train.astype('float32') / 255 x_train array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32) x_test = np.reshape(x_test, [-1, input_size]) x_test array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], dtype=uint8) x_test = x_test.astype('float32') / 255 x_test array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32) MLPモデルの構築 batch_size = 128 hidden_units = 256 dropout = 0.45 model = Sequential() model.add(Dense(hidden_units, input_dim=input_size)) model.add(Activation('relu')) model.add(Dropout(dropout)) model.add(Dense(hidden_units)) model.add(Activation('relu')) model.add(Dropout(dropout)) model.add(Dense(num_labels)) model.add(Activation('softmax')) model.summary() Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense (Dense) (None, 256) 200960 _________________________________________________________________ activation (Activation) (None, 256) 0 _________________________________________________________________ dropout (Dropout) (None, 256) 0 _________________________________________________________________ dense_1 (Dense) (None, 256) 65792 _________________________________________________________________ activation_1 (Activation) (None, 256) 0 _________________________________________________________________ dropout_1 (Dropout) (None, 256) 0 _________________________________________________________________ dense_2 (Dense) (None, 10) 2570 _________________________________________________________________ activation_2 (Activation) (None, 10) 0 ================================================================= Total params: 269,322 Trainable params: 269,322 Non-trainable params: 0 _________________________________________________________________ plot_model(model, show_shapes=True) model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy']) model.fit(x_train,y_train,epochs=20,batch_size=batch_size) Epoch 1/20 469/469 [==============================] - 4s 7ms/step - loss: 0.7162 - accuracy: 0.7716: Epoch 2/20 469/469 [==============================] - 3s 7ms/step - loss: 0.2036 - accuracy: 0.9380 Epoch 3/20 469/469 [==============================] - 4s 8ms/step - loss: 0.1617 - accuracy: 0.9510 Epoch 4/20 469/469 [==============================] - 3s 7ms/step - loss: 0.1259 - accuracy: 0.9616 Epoch 5/20 469/469 [==============================] - 3s 6ms/step - loss: 0.1117 - accuracy: 0.9643 Epoch 6/20 469/469 [==============================] - 3s 7ms/step - loss: 0.1022 - accuracy: 0.9688 Epoch 7/20 469/469 [==============================] - 4s 7ms/step - loss: 0.0918 - accuracy: 0.9713: 0s - l Epoch 8/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0834 - accuracy: 0.9730 Epoch 9/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0820 - accuracy: 0.9746 Epoch 10/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0756 - accuracy: 0.9765 Epoch 11/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0731 - accuracy: 0.9760 Epoch 12/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0691 - accuracy: 0.9778 Epoch 13/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0692 - accuracy: 0.9781 Epoch 14/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0601 - accuracy: 0.9809 Epoch 15/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0631 - accuracy: 0.9794 Epoch 16/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0550 - accuracy: 0.9831 Epoch 17/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0565 - accuracy: 0.9813 Epoch 18/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0532 - accuracy: 0.9831: 0s - los Epoch 19/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0515 - accuracy: 0.9830 Epoch 20/20 469/469 [==============================] - 3s 7ms/step - loss: 0.0530 - accuracy: 0.9824 <tensorflow.python.keras.callbacks.History at 0x1b5c0437cd0> _,acc = model.evaluate(x_test,y_test,batch_size=batch_size,verbose=0) acc*100 98.33999872207642 的中率98.3%の学習済みモデルが作成できた。 予測 model.predict(np.reshape(x_test[0],(1,784))).argmax() 7 y_test[0].argmax() 7 テストデータの0番目による予測値はラベルと一致しているようです。 from PIL import Image Image.fromarray((np.reshape(x_test[0],(28,28))*255).astype(np.uint8),'L') 肉眼で見ても正しく感じられます。 from sklearn import metrics metrics.confusion_matrix(y_test.argmax(axis=1), model.predict(x_test).argmax(axis=1)) array([[ 974, 1, 1, 0, 0, 1, 1, 0, 1, 1], [ 0, 1126, 2, 2, 0, 0, 2, 0, 3, 0], [ 3, 1, 1017, 2, 1, 0, 1, 5, 2, 0], [ 0, 0, 3, 995, 0, 3, 0, 5, 2, 2], [ 2, 0, 2, 1, 972, 0, 2, 1, 0, 2], [ 2, 0, 0, 9, 0, 872, 4, 0, 4, 1], [ 6, 2, 0, 1, 4, 2, 942, 0, 1, 0], [ 1, 2, 8, 2, 1, 0, 0, 1008, 2, 4], [ 7, 0, 2, 2, 5, 3, 0, 3, 947, 5], [ 2, 2, 0, 3, 14, 2, 1, 4, 0, 981]], dtype=int64) Confusion Matrixをみると対角成分が大きくなっているのは正解が多いからです。14という数字の位置はラベルが9に対して4を予測したという誤りが多いことを示しています。 小ネタですが、Sympyを使うと、行列が見やすくなりますのでオススメです。(Jupyterを使用) from sympy import Matrix Matrix(metrics.confusion_matrix(y_test.argmax(axis=1), model.predict(x_test).argmax(axis=1))) $\displaystyle \left[\begin{matrix}974 & 1 & 1 & 0 & 0 & 1 & 1 & 0 & 1 & 1\\0 & 1126 & 2 & 2 & 0 & 0 & 2 & 0 & 3 & 0\\3 & 1 & 1017 & 2 & 1 & 0 & 1 & 5 & 2 & 0\\0 & 0 & 3 & 995 & 0 & 3 & 0 & 5 & 2 & 2\\2 & 0 & 2 & 1 & 972 & 0 & 2 & 1 & 0 & 2\\2 & 0 & 0 & 9 & 0 & 872 & 4 & 0 & 4 & 1\\6 & 2 & 0 & 1 & 4 & 2 & 942 & 0 & 1 & 0\\1 & 2 & 8 & 2 & 1 & 0 & 0 & 1008 & 2 & 4\\7 & 0 & 2 & 2 & 5 & 3 & 0 & 3 & 947 & 5\\2 & 2 & 0 & 3 & 14 & 2 & 1 & 4 & 0 & 981\end{matrix}\right]$ 誤りの箇所をよくみる 正解できる場合より、正しく予測できない場合をよく観察したほうが勉強になる気がしました。 fails = [(i,(np.reshape(x_test[i],(28,28))*255).astype(np.uint8),x.argmax(),y.argmax()) for i,(x,y) in enumerate(zip(model.predict(x_test),y_test)) if x.argmax()!=y.argmax()] len(fails) 166 誤っているときの予測値とラベルの組み合わせとその出現数をまとめてみました。 dict(zip(*np.unique([str({'predict':x.argmax(),'label':y.argmax()}) for x,y in zip(model.predict(x_test),y_test) if x.argmax()!=y.argmax()],return_counts=True))) { "{'predict': 0, 'label': 2}": 3, "{'predict': 0, 'label': 4}": 2, "{'predict': 0, 'label': 5}": 2, "{'predict': 0, 'label': 6}": 6, "{'predict': 0, 'label': 7}": 1, "{'predict': 0, 'label': 8}": 7, "{'predict': 0, 'label': 9}": 2, "{'predict': 1, 'label': 0}": 1, "{'predict': 1, 'label': 2}": 1, "{'predict': 1, 'label': 6}": 2, "{'predict': 1, 'label': 7}": 2, "{'predict': 1, 'label': 9}": 2, "{'predict': 2, 'label': 0}": 1, "{'predict': 2, 'label': 1}": 2, "{'predict': 2, 'label': 3}": 3, "{'predict': 2, 'label': 4}": 2, "{'predict': 2, 'label': 7}": 8, "{'predict': 2, 'label': 8}": 2, "{'predict': 3, 'label': 1}": 2, "{'predict': 3, 'label': 2}": 2, "{'predict': 3, 'label': 4}": 1, "{'predict': 3, 'label': 5}": 9, "{'predict': 3, 'label': 6}": 1, "{'predict': 3, 'label': 7}": 2, "{'predict': 3, 'label': 8}": 2, "{'predict': 3, 'label': 9}": 3, "{'predict': 4, 'label': 2}": 1, "{'predict': 4, 'label': 6}": 4, "{'predict': 4, 'label': 7}": 1, "{'predict': 4, 'label': 8}": 5, "{'predict': 4, 'label': 9}": 14, "{'predict': 5, 'label': 0}": 1, "{'predict': 5, 'label': 3}": 3, "{'predict': 5, 'label': 6}": 2, "{'predict': 5, 'label': 8}": 3, "{'predict': 5, 'label': 9}": 2, "{'predict': 6, 'label': 0}": 1, "{'predict': 6, 'label': 1}": 2, "{'predict': 6, 'label': 2}": 1, "{'predict': 6, 'label': 4}": 2, "{'predict': 6, 'label': 5}": 4, "{'predict': 6, 'label': 9}": 1, "{'predict': 7, 'label': 2}": 5, "{'predict': 7, 'label': 3}": 5, "{'predict': 7, 'label': 4}": 1, "{'predict': 7, 'label': 8}": 3, "{'predict': 7, 'label': 9}": 4, "{'predict': 8, 'label': 0}": 1, "{'predict': 8, 'label': 1}": 3, "{'predict': 8, 'label': 2}": 2, "{'predict': 8, 'label': 3}": 2, "{'predict': 8, 'label': 5}": 4, "{'predict': 8, 'label': 6}": 1, "{'predict': 8, 'label': 7}": 2, "{'predict': 9, 'label': 0}": 1, "{'predict': 9, 'label': 3}": 2, "{'predict': 9, 'label': 4}": 2, "{'predict': 9, 'label': 5}": 1, "{'predict': 9, 'label': 7}": 4, "{'predict': 9, 'label': 8}": 5 } Confusion Matrixを見慣れていないので、自分にはコッチのほうがわかりやすいです。縦横のどっちがラベルなのかこんがらがります。 さいごに、一体どんな画像を読み誤っていたのかを列挙します。これは人の目で見ても判断がつかんだろうと思うものも多いです。 plt.figure(figsize=(6,8),dpi=200) for n,(i,img,x,y) in enumerate(fails): plt.subplot(10,17,n+1) plt.title(str(i)+':\npred:'+str(x)+'\nlabel:'+str(y),fontsize=4) plt.imshow(img,cmap='gray') plt.axis('off') plt.show() よく見るとむしろラベルの間違いを疑うような無理ゲーっぽいのがあるので、的中率100%は必ずしもいいモデルとは言えないでしょうね(汎化性能が落ちる)。 機械学習の初歩中の初歩はこれでクリアです。ランダムシードを固定しないと結果が毎回変わってしまうことを勉強するのにも役立ちました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TecoGAN で低解像度の動画を高解像度化

TecoGAN で低解像度の動画を高解像度化します。 環境はUbuntu20になります。 結構重いので、GPUを使うか、事前にffmpegで動画を縮小すると良いかもしれません。 install_tecogan.sh #!/usr/bin/bash # ========================================================== # TecoGan 用に python3.6.8 を仮想環境にインストール # ========================================================== sudo echo ; sudo apt-get install ffmpeg ; sudo apt-get install python3-venv ; sudo apt install -y \ build-essential \ libffi-dev \ libssl-dev \ zlib1g-dev \ liblzma-dev \ libbz2-dev \ libreadline-dev \ libsqlite3-dev \ git ; git clone https://github.com/pyenv/pyenv.git ~/.pyenv ; echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc ; echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc ; echo 'eval "$(pyenv init -)"' >> ~/.bashrc ; source ~/.bashrc ; pyenv -v ; pyenv install 3.6.8 ; pyenv local 3.6.8 ; pyenv versions ; # ========================================================== # TecoGAN のインストール # ========================================================== git clone https://github.com/thunil/TecoGAN ; cd TecoGAN ; python3 -m venv myvenv-topgan ; source myvenv-topgan/bin/activate ; python -m pip install pip -U ; python -m pip install -r requirements.txt ; python -m pip uninstall -y Keras Keras-Applications Keras-Preprocessing ; python -m pip install keras==2.3.1 ; python -m pip install tensorflow-gpu==1.14.0 ; python runGan.py 0 ; # ライブラリ群をダウンロード python runGan.py 1 ; # サンプルとして、LR/calendar に入っている画像を results/calendar に出力します。 # checck LR/calendar/*.png # checck results/calendar/*.png # ========================================================== # 動画のダウンロードと動画を画像群化 # ========================================================== # 動画のダウンロード(できればサイズは横幅240程度が望ましい) # youtube-dl がない場合は下記コマンドでインストール # sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl ; # sudo chmod a+rx /usr/local/bin/youtube-dl ; youtube-dl https://www.youtube.com/watch?v=RmlSsON0oY0 ; # 一旦前回分の削除 mkdir LR/calendar_back ; cp LR/calendar/* LR/calendar_back ; rm LR/calendar/* rm results/calendar/* ; # 動画を画像群化 ffmpeg -i "ドリフ大爆笑1983年op-RmlSsON0oY0.mkv" -vcodec png LR/calendar/%d.png ; # 縮小して使用する場合 # ffmpeg -i "ドリフ大爆笑1983年op-RmlSsON0oY0.mkv" -vf scale=120:-1 "低解像度動画.mkv" ; # ffmpeg -i "低解像度動画.mkv" -vcodec png LR/calendar/%d.png ; # TecoGAN の実行 python runGan.py 1 ; # checck results/calendar/*.png # 画像群を動画化 ffmpeg -i results/calendar/output_%d.png -vcodec libx264 -pix_fmt yuv420p "最終結果動画.mp4" ; 参考リンク あとで記載します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む