自分用メモ 画像認識の練習
# --- 必要なモジュールインポート --- import os import pandas as pd import numpy as np import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras import layers, models from tensorflow.keras.applications import EfficientNetV2B0
# --- 1. ラベルファイルと画像ディレクトリの設定 --- data_dir = "./cifar10_subset" labels_path = os.path.join(data_dir, "labels.tsv") images_dir = os.path.join(data_dir, "images")
# --- 2. ラベル読み込み --- labels_df = pd.read_csv(labels_path, sep="\t") print(labels_df) labels_df["label"] = labels_df["label"].astype(str) print(labels_df)
# --- 3. ImageDataGenerator 準備 ---
datagen = ImageDataGenerator(
# rescale=1./255
validation_split=0.1,
# rotation_range=15, # 回転 ±15度
# width_shift_range=0.1, # 横方向 10%ずらす
# height_shift_range=0.1, # 縦方向 10%ずらす
# zoom_range=0.1, # 拡大縮小10%
# horizontal_flip=True, # 左右反転
)
# --- 4. Generator作成 ---
IMG_SIZE = 224
BATCH_SIZE = 32
train_generator = datagen.flow_from_dataframe(
dataframe=labels_df,
directory=images_dir,
x_col="filename",
y_col="label",
target_size=(IMG_SIZE, IMG_SIZE),
class_mode="categorical",
batch_size=BATCH_SIZE,
shuffle=True,
subset="training",
seed=42
)
val_generator = datagen.flow_from_dataframe(
dataframe=labels_df,
directory=images_dir,
x_col="filename",
y_col="label",
target_size=(IMG_SIZE, IMG_SIZE),
class_mode="categorical",
batch_size=BATCH_SIZE,
shuffle=True,
subset="validation",
seed=42
)
# --- 5. モデル構築 ---
base_model = EfficientNetV2B0(
include_top=False,
weights="imagenet",
input_shape=(IMG_SIZE, IMG_SIZE, 3)
)
base_model.trainable = False
inputs = layers.Input(shape=(IMG_SIZE, IMG_SIZE, 3))
x = base_model(inputs, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(10, activation="softmax")(x)
model = models.Model(inputs, outputs)
model.compile(
optimizer=tf.keras.optimizers.Adam(1e-2),
loss="categorical_crossentropy",
metrics=["accuracy"]
)
from tensorflow.keras.callbacks import ReduceLROnPlateau
# 学習率スケジューラの定義
lr_scheduler = ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=3,
verbose=1,
min_lr=1e-6
)
import tensorflow as tf
print("TensorFlow version:", tf.__version__)
print("Num GPUs Available:", len(tf.config.list_physical_devices('GPU')))
# 実際に使われているデバイスの確認
tf.debugging.set_log_device_placement(True)
# --- 6. モデル学習 ---
history = model.fit(
train_generator,
validation_data=val_generator,
epochs=10,
workers=8,
callbacks=[lr_scheduler],
# use_multiprocessing=True,
)
# --- 7. モデルFine-tuning(オプション) ---
base_model.trainable = True
# block6a以降だけ学習対象
set_trainable = False
for layer in base_model.layers:
if 'block6a' in layer.name:
set_trainable = True
layer.trainable = set_trainable
model.compile(
optimizer=tf.keras.optimizers.Adam(1e-4),
loss="categorical_crossentropy",
metrics=["accuracy"]
)
history_fine = model.fit(
train_generator,
validation_data=val_generator,
epochs=30,
workers=8,
callbacks=[lr_scheduler],
# use_multiprocessing=True,
)
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# 画像リサイズ(ここは一気にやってもいいけど、メモリ注意)
x_test_resized = tf.image.resize(x_test, (224, 224))
# スケーリング(0〜1化)
# x_test_resized = x_test_resized / 255.0
# 正解ラベルを one-hotに(今のモデルが 'categorical_crossentropy' だから)
from tensorflow.keras.utils import to_categorical
y_test_categorical = to_categorical(y_test, num_classes=10)
test_loss, test_acc = model.evaluate(x_test_resized, y_test_categorical, batch_size=32)
print("Test loss:", test_loss)
print("Test accuracy:", test_acc)
from tensorflow.keras.models import Model, load_model
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import cifar10
# モデルとデータの準備
#model = load_model("model/cifar10_model.h5") # モデルパスは適宜修正
(_, _), (x_test, _) = cifar10.load_data()
# EfficientNetV2のベースモデルを取得
effnet = model.get_layer("efficientnetv2-b0")
# 可視化したい層の名前(代表的なブロック)
layer_names = [
"stem_conv", # 入力
"block1a_project_activation", # 低レベル特徴抽出(色・線)
"block3a_expand_activation", # 中レベル特徴
"block4a_activation", # 中~高レベル
"block6a_activation", # 高レベル特徴
"top_activation", # 分類前最終活性
]
# 中間層モデル作成
intermediate_model = Model(
inputs=effnet.input,
outputs=[effnet.get_layer(name).output for name in layer_names]
)
# 画像準備(CIFAR-10の1枚をリサイズ)
img = x_test[0]
img_resized = tf.image.resize(img, (224, 224))
img_resized = np.expand_dims(img_resized, axis=0)
# 中間層出力を取得
feature_maps = intermediate_model.predict(img_resized)
# 入力画像表示
plt.figure(figsize=(2, 2))
plt.imshow(img)
plt.title("Input image")
plt.axis("off")
plt.show()
# 各層の出力を可視化(チャンネル先頭8個のみ)
for layer_name, fmap in zip(layer_names, feature_maps):
fig, axs = plt.subplots(1, 10, figsize=(15, 3))
fig.suptitle(layer_name)
for i in range(10):
axs[i].imshow(fmap[0, :, :, i], cmap='viridis')
axs[i].axis('off')
plt.show()
テスト
てすと