機械学習入門 - TensorFlow | オリジナル、AI翻訳

Home 2021.03

この記事はもともと中国語で書かれました。他の言語への翻訳を容易にするために英語に翻訳されました。


Python を学習しているので、機械学習について話さないわけにはいきません。多くのライブラリがPythonで書かれています。まずインストールして試してみましょう。

TensorFlow

インストールしましょう。

$ pip install tensorflow
ERROR: Could not find a version that satisfies the requirement tensorflow
ERROR: No matching distribution found for tensorflow
$ type python
python is aliased to `/usr/local/Cellar/python@3.9/3.9.1_6/bin/python3'

しかし、TensorFlow 2Python 3.5–3.8 しかサポートしていません。私たちが使っているのは 3.9 です。

% type python3
python3 is /usr/bin/python3
% python3 -V
Python 3.8.2

私のシステムの python33.8.2 であることに注意してください。このPythonバージョンに対応する pip はどこにパッケージをインストールするでしょうか?

% python3 -m pip -V
pip 21.0.1 from /Users/lzw/Library/Python/3.8/lib/python/site-packages/pip (python 3.8)

対応する pip はここにあります。そこで、.zprofile ファイルを修正します。最近、シェルを変更したので、.zprofile は以前の .bash_profile と同じです。1行追加します:

alias pip3=/Users/lzw/Library/Python/3.8/bin/pip3

これで、python3pip3 を使って TensorFlow を操作できます。

% pip3 install tensorflow
...
Successfully installed absl-py-0.12.0 astunparse-1.6.3 cachetools-4.2.1 certifi-2020.12.5 chardet-4.0.0 flatbuffers-1.12 gast-0.3.3 google-auth-1.27.1 google-auth-oauthlib-0.4.3 google-pasta-0.2.0 grpcio-1.32.0 h5py-2.10.0 idna-2.10 keras-preprocessing-1.1.2 markdown-3.3.4 numpy-1.19.5 oauthlib-3.1.0 opt-einsum-3.3.0 protobuf-3.15.6 pyasn1-0.4.8 pyasn1-modules-0.2.8 requests-2.25.1 requests-oauthlib-1.3.0 rsa-4.7.2 tensorboard-2.4.1 tensorboard-plugin-wit-1.8.0 tensorflow-2.4.1 tensorflow-estimator-2.4.0 termcolor-1.1.0 typing-extensions-3.7.4.3 urllib3-1.26.3 werkzeug-1.0.1 wheel-0.36.2 wrapt-1.12.1

多くのライブラリがインストールされました。公式サイトの例を使ってみましょう。

import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
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)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])

predictions = model(x_train[:1]).numpy()
print(predictions)

実行してみましょう。

$ /usr/bin/python3 tf.py
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 10s 1us/step
[[ 0.15477428 -0.3877643   0.0994779   0.07474922 -0.26219758 -0.03550266
   0.32226565 -0.37141111  0.10925996 -0.0115255 ]]

ご覧の通り、データセットがダウンロードされ、結果が出力されました。

次に、画像分類の例を見てみましょう。

# TensorFlow and tf.keras
import tensorflow as tf

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)

エラーが発生しました。

ModuleNotFoundError: No module named 'matplotlib'

インストールしましょう。

% pip3 install matplotlib

これで正常になりました。

$ /usr/bin/python3 image.py
2.4.1

例のコードをコピーして貼り付けます。

# TensorFlow and tf.keras
import tensorflow as tf

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

fashion_mnist = tf.keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
print(train_images.shape)
print(len(train_labels))

結果が出力されました。train_imagestrain_labelstest_imagestest_labels があることに注意してください。これらはトレーニングデータセットとテストデータセットに分割されています。

(60000, 28, 28)
60000

次に、画像を表示してみましょう。

print(train_images[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   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   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   0  13  73   0
    0   1   4   0   0   0   0   1   1   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   3   0  36 136 127  62
   54   0   0   0   1   3   4   0   0   3]
 [  0   0   0   0   0   0   0   0   0   0   0   0   6   0 102 204 176 134
  144 123  23   0   0   0   0  12  10   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0 155 236 207 178
  107 156 161 109  64  23  77 130  72  15]
 [  0   0   0   0   0   0   0   0   0   0   0   1   0  69 207 223 218 216
  216 163 127 121 122 146 141  88 172  66]]
  ....

ここでは、結果の一部を抜粋しています。

print(len(train_images[0][0]))

出力は 28 です。つまり、これは幅28の行列であることがわかります。引き続き表示しましょう。

print(len(train_images[0][0][0]))
TypeError: object of type 'numpy.uint8' has no len()

これで明らかになりました。各画像は 28*28*3 の配列です。最後の次元にはRGBの値が格納されています。しかし、これは間違っている可能性があります。

print(train_images[0][1][20])
0
print(train_images[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 0]

これを見ると、各画像は 28*28 の配列であることがわかります。少し試行錯誤した後、ようやく秘密がわかりました。

まず、出力画像を見てみましょう。

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()

tf

右側のカラーバーが見えますか?0 から 250 までです。これは2つの色の間のグラデーションであることがわかりました。しかし、どのようにして2つの色を知るのでしょうか?どこで指定したのでしょうか?

次に、2番目の画像も表示してみましょう。

plt.imshow(train_images[1])

plt

非常に興味深いです。これは pyplot ライブラリのデフォルトでしょうか?公式サイトが提供するコードを引き続き実行してみましょう。

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

tf2

ここで、画像とその分類が表示されていることに注意してください。最終的に、cmap パラメータの意味がわかりました。cmap を指定しない場合、先ほど見た色のスキームがデフォルトで適用されます。

plt.imshow(train_images[i])

cmap

今度は pyplot cmap を検索して、いくつかのリソースを見つけます。

plt.imshow(train_images[i], cmap=plt.cm.PiYG)

cmap1

コードを変更しましょう。

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(2,5,i+1)   ## この行を変更
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.Blues)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

しかし、エラーが発生しました。

ValueError: num must be 1 <= num <= 10, not 11

これはどういう意味でしょうか?前の 5,5,i+1 は具体的にどういう意味でしょうか?2 に変更するとなぜ動作しないのでしょうか?直感的には5行5列を意味すると思いますが、なぜこのエラーが発生するのでしょうか?11 はどのように計算されるのでしょうか?num とは何でしょうか?10 とは何でしょうか?2*5=10 に注意してください。そのため、おそらく i=11 のときにエラーが発生します。for i in range(10): に変更すると、次の結果が得られます。

plot3

今度は簡単にドキュメントを見てみると、subplot(nrows, ncols, index, **kwargs) について学びます。これで理解できました。

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    # plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.Blues)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

plot_xticks

0 25 のようなものは xticks と呼ばれます。このフレームを拡大または縮小すると、表示が変わります。

plot_scale

拡大または縮小すると、xticksxlabels の表示が変わることに注意してください。

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10)
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=10)

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)

ここでモデルの定義方法に注意してください。Sequential クラスを使用しています。これらのパラメータに注意してください:28,28128relu10compilefit が必要であることに注意してください。fit はフィッティングを意味します。28,28 は画像のサイズに対応していることに注意してください。

Epoch 1/10
1875/1875 [==============================] - 2s 928us/step - loss: 0.6331 - accuracy: 0.7769
Epoch 2/10
1875/1875 [==============================] - 2s 961us/step - loss: 0.3860 - accuracy: 0.8615
Epoch 3/10
1875/1875 [==============================] - 2s 930us/step - loss: 0.3395 - accuracy: 0.8755
Epoch 4/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.3071 - accuracy: 0.8890
Epoch 5/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2964 - accuracy: 0.8927
Epoch 6/10
1875/1875 [==============================] - 2s 985us/step - loss: 0.2764 - accuracy: 0.8955
Epoch 7/10
1875/1875 [==============================] - 2s 961us/step - loss: 0.2653 - accuracy: 0.8996
Epoch 8/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2549 - accuracy: 0.9052
Epoch 9/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2416 - accuracy: 0.9090
Epoch 10/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2372 - accuracy: 0.9086
313/313 - 0s - loss: 0.3422 - accuracy: 0.8798

Test accuracy: 0.879800021648407

モデルはトレーニングされました。パラメータを調整してみましょう。

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(28, activation='relu'),    # 128 -> 28
    tf.keras.layers.Dense(10)
])

Dense の最初のパラメータを変更します。

Epoch 1/10
1875/1875 [==============================] - 2s 714us/step - loss: 6.9774 - accuracy: 0.3294
Epoch 2/10
1875/1875 [==============================] - 1s 715us/step - loss: 1.3038 - accuracy: 0.4831
Epoch 3/10
1875/1875 [==============================] - 1s 747us/step - loss: 1.0160 - accuracy: 0.6197
Epoch 4/10
1875/1875 [==============================] - 1s 800us/step - loss: 0.7963 - accuracy: 0.6939
Epoch 5/10
1875/1875 [==============================] - 2s 893us/step - loss: 0.7006 - accuracy: 0.7183
Epoch 6/10
1875/1875 [==============================] - 1s 747us/step - loss: 0.6675 - accuracy: 0.7299
Epoch 7/10
1875/1875 [==============================] - 1s 694us/step - loss: 0.6681 - accuracy: 0.7330
Epoch 8/10
1875/1875 [==============================] - 1s 702us/step - loss: 0.6675 - accuracy: 0.7356
Epoch 9/10
1875/1875 [==============================] - 1s 778us/step - loss: 0.6508 - accuracy: 0.7363
Epoch 10/10
1875/1875 [==============================] - 1s 732us/step - loss: 0.6532 - accuracy: 0.7350
313/313 - 0s - loss: 0.6816 - accuracy: 0.7230

Test accuracy: 0.7229999899864197

Test accuracy の前後の変化に注意してください。Epoch ログは fit 関数によって出力されます。128 の場合、accuracy0.7769 から 0.9086 になります。28 の場合、accuracy0.3294 から 0.7350 になります。今回は、まずトレーニングセットを使用して lossaccuracy を最適化し、その後テストデータセットを使用して評価することがわかりました。train_labels を見てみましょう。

print(train_labels)
[9 0 0 ... 3 0 5]
print(len(train_labels))
60000

これは、数字 0 から 9 がこれらのカテゴリを表すことを意味します。偶然にも、class_names も10個のアイテムがあります。

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

もう一つ変更を加えてみましょう。

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(28, activation='relu'),
    tf.keras.layers.Dense(5)   # 10 -> 5
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=10)

エラーが発生しました。

tensorflow.python.framework.errors_impl.InvalidArgumentError:  Received a label value of 9 which is outside the valid range of [0, 5).  Label values: 4 3 2 9 4 1 6 0 7 9 1 6 5 2 3 8 6 3 8 0 3 5 6 1 2 6 3 6 8 4 8 4
         [[node sparse_categorical_crossentropy/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits (defined at /curiosity-courses/ml/tf/image.py:53) ]] [Op:__inference_train_function_538]

Function call stack:
train_function

Sequential の3番目のパラメータ Dense15 に変更すると問題は解決します。結果はそれほど変わりません。Epoch を変更してみましょう。

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(28, activation='relu'),
    tf.keras.layers.Dense(15)
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=15)  # 10 -> 15

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)
Epoch 1/15
1875/1875 [==============================] - 2s 892us/step - loss: 6.5778 - accuracy: 0.3771
Epoch 2/15
1875/1875 [==============================] - 2s 872us/step - loss: 1.3121 - accuracy: 0.4910
Epoch 3/15
1875/1875 [==============================] - 2s 909us/step - loss: 1.0900 - accuracy: 0.5389
Epoch 4/15
1875/1875 [==============================] - 1s 730us/step - loss: 1.0422 - accuracy: 0.5577
Epoch 5/15
1875/1875 [==============================] - 1s 709us/step - loss: 0.9529 - accuracy: 0.5952
Epoch 6/15
1875/1875 [==============================] - 1s 714us/step - loss: 0.9888 - accuracy: 0.5950
Epoch 7/15
1875/1875 [==============================] - 1s 767us/step - loss: 0.8678 - accuracy: 0.6355
Epoch 8/15
1875/1875 [==============================] - 1s 715us/step - loss: 0.8247 - accuracy: 0.6611
Epoch 9/15
1875/1875 [==============================] - 1s 721us/step - loss: 0.8011 - accuracy: 0.6626
Epoch 10/15
1875/1875 [==============================] - 1s 711us/step - loss: 0.8024 - accuracy: 0.6622
Epoch 11/15
1875/1875 [==============================] - 1s 781us/step - loss: 0.7777 - accuracy: 0.6696
Epoch 12/15
1875/1875 [==============================] - 1s 724us/step - loss: 0.7764 - accuracy: 0.6728
Epoch 13/15
1875/1875 [==============================] - 1s 731us/step - loss: 0.7688 - accuracy: 0.6767
Epoch 14/15
1875/1875 [==============================] - 1s 715us/step - loss: 0.7592 - accuracy: 0.6793
Epoch 15/15
1875/1875 [==============================] - 1s 786us/step - loss: 0.7526 - accuracy: 0.6792
313/313 - 0s - loss: 0.8555 - accuracy: 0.6418

Test accuracy: 0.6417999863624573

15に変更してもそれほど違いはありません。tf.keras.layers.Dense(88, activation='relu') が重要です。12888 に変更すると、Test accuracy: 0.824999988079071 になります。128 の場合は 0.879800021648407 でしたが、28 の場合は 0.7229999899864197 でした。より大きな値が良い結果をもたらすのでしょうか?しかし、256 に変更すると Test accuracy: 0.8409000039100647 になります。これにより、lossaccuracy の意味について考えさせられます。

probability_model = tf.keras.Sequential([model,
                                         tf.keras.layers.Softmax()])

次に、予測を行ってみましょう。Sequential は上記と同じであることに注意してください。パラメータ modeltf.keras.layers.Softmax() に注意してください。

probability_model = tf.keras.Sequential([model,
                                         tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)

def plot_image(i, predictions_array, true_label, img):
  true_label, img = true_label[i], img[i]
  plt.grid(False)
  plt.xticks([])
  plt.yticks([])

  plt.imshow(img, cmap=plt.cm.binary)

  predicted_label = np.argmax(predictions_array)
  if predicted_label == true_label:
    color = 'blue'
  else:
    color = 'red'

  plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                100*np.max(predictions_array),
                                class_names[true_label]),
                                color=color)

def plot_value_array(i, predictions_array, true_label):
  true_label = true_label[i]
  plt.grid(False)
  plt.xticks(range(10))
  plt.yticks([])
  thisplot = plt.bar(range(10), predictions_array, color="#777777")
  plt.ylim([0, 1])
  predicted_label = np.argmax(predictions_array)

  thisplot[predicted_label].set_color('red')
  thisplot[true_label].set_color('blue')

i = 0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()

pred

これは、この画像が Ankle boot である確率が99%であることを示しています。plot_image が左のチャートを表示し、plot_value_array が右のチャートを出力することに注意してください。

num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions[i], test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()

pred1

これにより、さらに多くのテスト結果が表示されます。そのため、大まかな使用フローが理解できました。背後の計算方法はまだわかりませんが、使用方法は理解しています。背後には微積分があります。微積分をどのように理解するのでしょうか?

例えば、1から100の範囲で数字を当てるゲームがあるとします。あなたが数字を当てると、私はそれが低すぎるか高すぎるかを教えます。あなたが50と推測します。私は低すぎると言います。あなたが80と推測します。私は高すぎると言います。あなたが65と推測します。私は高すぎると言います。あなたが55と推測します。私は低すぎると言います。あなたが58と推測します。私は、はい、当たりですと言います。

機械学習は裏で同様のプロセスをシミュレートしていますが、より複雑です。多くの 1から100 のような範囲が関与し、一度に多くの数字を推測することができます。各推測には多くの計算が含まれ、高すぎるか低すぎるかを判断するのにも多くの計算が必要です。


Back Donate