地球暦2045年、都市は廃墟と化し、世界は無秩序に満ちていた。生き残った人類は、未来を予測するAI「サイコザク」に頼るしかなかった。サイコザクはシンプルだが強力なニューラルネットワークを持ち、特に動画フレームの予測において無類の性能を誇っていた。サイコザクの予測は常に正確で、人々はその未来視を信じて行動していた。
一章: 希望の芽生え
イーヴァは荒廃した都市の一角で、サイコザクの前に立っていた。彼女はグループのリーダーであり、仲間の生存を賭けた次の移動先をサイコザクに問いかけた。
「次の安全な場所はどこ?」イーヴァが尋ねる。
サイコザクの巨大なスクリーンに映像が映し出される。サイコザクのシンプルなニューラルネットワークは、過去のデータと現在の状況をもとに次の数秒間の映像を生成する。その映像はまるで未来を覗き見るかのようだった。
映像には、静かな森とそこに潜む危険の兆候が映し出されていた。イーヴァはその未来視を注意深く観察し、仲間たちに指示を出した。「次の目的地は東の森。映像に見える罠に気をつけて。」
二章: サイコザクの性能
サイコザクの核心技術は、そのシンプルな巨大重み行列にあった。人類がこれほどの予測精度を持つAIを作り上げるまでに、数多くの失敗と試行錯誤があった。サイコザクの開発者であるドクター・ハンセンは、その性能に驚嘆していた。
「このシンプルなネットワークが、これほどの予測精度を持つとは…」ドクター・ハンセンは独り言をつぶやいた。
サイコザクは、全ての入力データを一つの巨大な重み行列に通すだけで未来のフレームを予測する。その驚異的なシンプルさが、逆に性能の秘訣であった。無数のノイズを除去し、最も重要な情報だけを抽出することで、高精度の予測を実現していた。
三章: 未来視の代償
イーヴァたちはサイコザクの予測を頼りに進んでいたが、その未来視には代償があった。サイコザクの予測が100%正確でないこともあった。ある日、彼女たちはサイコザクの映像通りに進んだが、そこには予想外の敵が待ち構えていた。
「これは…映像には映ってなかった!」仲間の一人が叫ぶ。
サイコザクの予測は確かに高精度だったが、完璧ではなかった。未来は常に変動し、予測はあくまで可能性の一つに過ぎなかった。イーヴァはそのことを痛感し、サイコザクに完全に依存することの危険性を悟った。
エピローグ: 新たな一歩
敵との戦いを経て、イーヴァたちは再びサイコザクの前に戻ってきた。彼女は慎重にサイコザクの映像を分析し、新たな戦略を練った。
「サイコザクの予測は重要だけど、私たちの判断も同じくらい重要だ。」イーヴァは決意を新たに仲間たちに語った。
サイコザクのシンプルなネットワークは未来を見通す力を持っていたが、最終的に未来を切り開くのは人間自身だった。イーヴァたちはサイコザクの予測を活かしながら、自らの力で未来を切り拓いていく決意を固めた。
そして、荒廃した都市に新たな希望の光が灯り始めた。サイコザクと人々の共闘が、新たな未来を創り出す第一歩となった。
同じラベルの画像ペアを作成しペアの画像を予測してます。
モデルの weight_size を変更してトレーニングを実行し、トレーニングロスの変化を観察します。次のように weight_size を1000、2000、3000、4000に設定し、それぞれのトレーニングロスを記録してプロットします。
トレーニングサンプルの数を増やしていきます。次第に学習が困難になっていきます。
num_samples = 100
Training with weight_size=1000
Training with weight_size=2000
Training with weight_size=3000
Training with weight_size=4000
num_samples = 120
Training with weight_size=1000
Training with weight_size=2000
Training with weight_size=3000
Training with weight_size=4000
num_samples = 160
Training with weight_size=1000
Training with weight_size=2000
Training with weight_size=3000
Training with weight_size=4000
num_samples = 200
Training with weight_size=1000
Training with weight_size=2000
Training with weight_size=3000
Training with weight_size=4000
num_samples = 300
Training with weight_size=1000
Training with weight_size=2000
Training with weight_size=3000
Training with weight_size=4000
num_samples = 300 大容量の新型モデル で検証。
戦いはまだまだつつく。
このシンプルなネットワークが、これほどの予測精度を持つとは…のコード。
import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models, callbacks
import matplotlib.pyplot as plt
# CIFAR-10データセットの読み込み
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# データの前処理(正規化)
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
num_samples = 100
epochs = 1000
batch_size = 10
# 同じラベルの画像ペアを作成する関数
def create_pairs(x, y, num_pairs=num_samples):
pairs = []
labels = []
num_classes = len(np.unique(y))
digit_indices = [np.where(y == i)[0] for i in range(num_classes)]
for d in range(num_classes):
np.random.shuffle(digit_indices[d]) # Shuffle indices to get random pairs
for i in range(min(len(digit_indices[d]) - 1, num_pairs // num_classes)):
z1, z2 = digit_indices[d][i], digit_indices[d][i + 1]
pairs += [[x[z1], x[z2]]]
labels += [1]
if len(pairs) >= num_pairs:
break
return np.array(pairs), np.array(labels)
# 訓練用ペアを作成(100ペア)
train_pairs, train_labels = create_pairs(x_train, y_train, num_pairs=num_samples)
# モデルの定義
def create_model(input_shape, weight_size):
input = layers.Input(shape=input_shape)
x = layers.Flatten()(input)
encoded = layers.Dense(weight_size, activation='relu')(x)
encoder = models.Model(input, encoded, name='encoder')
encoded_input = layers.Input(shape=(weight_size,))
x = layers.Dense(np.prod(input_shape), activation='sigmoid')(encoded_input)
decoded = layers.Reshape(input_shape)(x)
decoder = models.Model(encoded_input, decoded, name='decoder')
autoencoder = models.Model(input, decoder(encoder(input)), name='autoencoder')
return autoencoder
# カスタムコールバックの定義
class PlotReconstructedImages(callbacks.Callback):
def __init__(self):
super().__init__()
def on_epoch_end(self, epoch, logs=None):
if (epoch + 1) % 200 == 0 or epoch == 0:
self.plot_images(epoch)
def plot_images(self, epoch):
indices = np.random.choice(len(train_pairs), 10, replace=False)
sampled_pairs = train_pairs[indices]
decoded_imgs = self.model.predict(sampled_pairs[:, 0])
n = 10 # プロットする画像の数
plt.figure(figsize=(20, 4))
for i in range(n):
# オリジナル画像
ax = plt.subplot(2, n, i + 1)
plt.imshow(sampled_pairs[i, 0])
plt.title("Original")
plt.axis("off")
# 再構成画像
ax = plt.subplot(2, n, i + 1 + n)
plt.imshow(decoded_imgs[i])
plt.title("Reconstructed")
plt.axis("off")
plt.suptitle(f'Epoch {epoch+1}')
plt.show()
# weight_sizeのリスト
weight_sizes = [1000, 2000, 3000, 4000]
losses = {}
# 各weight_sizeでモデルを訓練
for weight_size in weight_sizes:
print(f"Training with weight_size={weight_size}")
autoencoder = create_model((32, 32, 3), weight_size)
autoencoder.compile(optimizer='adam', loss='mse')
plot_callback = PlotReconstructedImages()
history = autoencoder.fit(train_pairs[:, 0], train_pairs[:, 1],
epochs=epochs,
batch_size=batch_size,
shuffle=True,
verbose=0, # 損失をプリントしない
callbacks=[plot_callback])
# 訓練ロスを保存
losses[weight_size] = history.history['loss']
# トレーニングロスのプロット
plt.figure(figsize=(10, 6))
for weight_size in weight_sizes:
plt.plot(losses[weight_size], label=f'weight_size={weight_size}')
plt.xlabel('Epoch')
plt.ylabel('Training Loss')
plt.legend()
plt.title('Training Loss for Different Weight Sizes')
plt.show()