
彼に年収や人格で負けているなら、
せめてじゃんけんくらい勝たせてほしいですよね。
ということで、
今回はTensorFlowを使って、画像分類器で
ヒカキンブンブンじゃんけんに勝たせるAIをつくります。
準備するもの
- Google Colaboratory(※Jupyter NotebookでもOK)
- 配布ソースコード(※一からやりたい方は不要)
ヒカキンブンブンじゃんけんに勝たせるAIのつくり方
じゃんけんをAIに学習させる
まずは、じゃんけんの画像が入っているzipファイルをダウンロードします。
!wget --no-check-certificate \
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps.zip \
-O /tmp/rps.zip
!wget --no-check-certificate \
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps-test-set.zip \
-O /tmp/rps-test-set.zip
`
–2022-09-19 05:51:56– https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps.zip
Resolving storage.googleapis.com (storage.googleapis.com)… 172.217.194.128, 142.251.10.128, 142.251.12.128, …
Connecting to storage.googleapis.com (storage.googleapis.com)|172.217.194.128|:443… connected.
HTTP request sent, awaiting response… 200 OK
Length: 200682221 (191M) [application/zip]
Saving to: ‘/tmp/rps.zip’
/tmp/rps.zip 100%[===================>] 191.38M 40.7MB/s in 4.7s
2022-09-19 05:52:02 (40.7 MB/s) – ‘/tmp/rps.zip’ saved [200682221/200682221]
–2022-09-19 05:52:02– https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps-test-set.zip
Resolving storage.googleapis.com (storage.googleapis.com)… 172.217.194.128, 142.251.10.128, 142.251.12.128, …
Connecting to storage.googleapis.com (storage.googleapis.com)|172.217.194.128|:443… connected.
HTTP request sent, awaiting response… 200 OK
Length: 29516758 (28M) [application/zip]
Saving to: ‘/tmp/rps-test-set.zip’
/tmp/rps-test-set.z 100%[===================>] 28.15M –.-KB/s in 0.1s
2022-09-19 05:52:02 (204 MB/s) – ‘/tmp/rps-test-set.zip’ saved [29516758/29516758]
`
zipを解凍して/tmp/
ディレクトリに保存します。
import os
import zipfile
local_zip = '/tmp/rps.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp/')
zip_ref.close()
local_zip = '/tmp/rps-test-set.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp/')
zip_ref.close()
学習用のじゃんけんの画像をグー
、チョキ
、パー
に分類します。
rock_dir = os.path.join('/tmp/rps/rock')
paper_dir = os.path.join('/tmp/rps/paper')
scissors_dir = os.path.join('/tmp/rps/scissors')
print('total training rock images:', len(os.listdir(rock_dir)))
print('total training paper images:', len(os.listdir(paper_dir)))
print('total training scissors images:', len(os.listdir(scissors_dir)))
rock_files = os.listdir(rock_dir)
print(rock_files[:10])
paper_files = os.listdir(paper_dir)
print(paper_files[:10])
scissors_files = os.listdir(scissors_dir)
print(scissors_files[:10])
total training rock images: 840 total training paper images: 840 total training scissors images: 840 ['rock01-027.png', 'rock05ck01-108.png', 'rock05ck01-090.png', 'rock01-040.png', 'rock02-108.png', 'rock02-022.png', 'rock01-060.png', 'rock07-k03-061.png', 'rock06ck02-032.png', 'rock03-069.png'] ['paper05-114.png', 'paper03-099.png', 'paper06-011.png', 'paper07-053.png', 'paper03-040.png', 'paper07-040.png', 'paper05-082.png', 'paper07-116.png', 'paper01-041.png', 'paper07-035.png'] ['scissors04-034.png', 'testscissors01-033.png', 'testscissors03-058.png', 'testscissors01-087.png', 'testscissors03-044.png', 'testscissors01-040.png', 'scissors04-080.png', 'scissors03-069.png', 'testscissors03-088.png', 'scissors04-038.png']
プロットします。
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
pic_index = 2
next_rock = [os.path.join(rock_dir, fname)
for fname in rock_files[pic_index-2:pic_index]]
next_paper = [os.path.join(paper_dir, fname)
for fname in paper_files[pic_index-2:pic_index]]
next_scissors = [os.path.join(scissors_dir, fname)
for fname in scissors_files[pic_index-2:pic_index]]
for i, img_path in enumerate(next_rock+next_paper+next_scissors):
img = mpimg.imread(img_path)
plt.imshow(img)
plt.axis('Off')
plt.show()

学習します。
import tensorflow as tf
import keras_preprocessing
from keras_preprocessing import image
from keras_preprocessing.image import ImageDataGenerator
TRAINING_DIR = "/tmp/rps/"
training_datagen = ImageDataGenerator(
rescale = 1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
VALIDATION_DIR = "/tmp/rps-test-set/"
validation_datagen = ImageDataGenerator(rescale = 1./255)
# 学習データをつくる
train_generator = training_datagen.flow_from_directory(
TRAINING_DIR,
target_size=(150,150),
class_mode='categorical',
batch_size=126
)
# 検証データをつくる
validation_generator = validation_datagen.flow_from_directory(
VALIDATION_DIR,
target_size=(150,150),
class_mode='categorical',
batch_size=126
)
# ニューラルネットワークを定義する
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(3, activation='softmax')
])
# 要約
model.summary()
# ニューラルネットワークをコンパイルする
model.compile(loss = 'categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
# 学習する
history = model.fit(train_generator, epochs=25, steps_per_epoch=20, validation_data = validation_generator, verbose = 1, validation_steps=3)
model.save("rps.h5")
学習が終わりました。
ヒカキンとじゃんけんをして、AIに勝たせる
これでファイルをアップロードして、ヒカキンに勝つ手を出力します。
import numpy as np
from google.colab import files
from keras.preprocessing import image
uploaded = files.upload()
for fn in uploaded.keys():
path = fn
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
hikakin_result = np.array(classes[0])
paper = np.array([1, 0, 0])
rock = np.array([0, 1, 0])
scissors = np.array([0, 0, 1])
if hikakin_result[0] == paper[0]:
print("✌")
if hikakin_result[1] == rock[1]:
print("🖐")
if hikakin_result[2] == scissors[2]:
print("✊")
上記を実行しましょう。
10回戦じゃんけんをしてみます。
Round 1


AIは✊を出しました。
よって、Round 1はAIの勝ち。
Round 2


AIは🖐を出しました。
よって、Round 2はAIの勝ち。
Round 3


AIは🖐を出しました。
よって、Round 3はあいこ。
Round 4


AIは✊を出しました。
よって、Round 4はAIの負け。
AIはパーを出されると弱いのでしょうか。
Round 5
3度目の正直なるか。


AIは✌を出しました。
よって、Round 5はAIの勝ち。
ようやく、パーに勝つことができました。
Round 6


AIは🖐を出しました。
よって、Round 6はAIの勝ち。
Round 7


AIは✌を出しました。
よって、Round 7はAIの勝ち。
Round 8


AIは✌を出しました。
よって、Round 8はAIの負け。
流石に、ぶれてるとダメでした。
Round 9


AIは✌を出しました。
よって、Round 9はAIの勝ち。
Round 10


AIは🖐を出しました。
よって、Round 10はAIの負け。
結果
Round | AI | ヒカキン |
---|---|---|
1 | ○ | |
2 | ○ | |
3 | – | – |
4 | ○ | |
5 | ○ | |
6 | ○ | |
7 | ○ | |
8 | ○ | |
9 | ○ | |
10 | ○ |
AIは 70% の確率でヒカキンブンブンじゃんけんに勝てる
ディープテックのマガジンはこちら『DeepMagazine』