【python】機械学習(教師あり)画像認識にて
調べてもどうしてもわからない部分が有り
すいませんが質問させていただきます。
【目的】
薬品容器を認識して容器の数を数えたい。
※機械学習(教師あり)にて容器の認識をしたいと考えております。
モデル学習する前にデータセットとして
薬品容器のアノテーション作業をLabelMEというツールで
容器のアノテーションを行い、ラベル付けしてjsonファイルにて保存しました。
(デスクトップの機械学習というフォルダにjsonファイル入れています。)
【質問】
このデータセットというのは
アノテーションした後のjsonファイルのみあれば
モデルの学習はできるのでしょうか?
モデル学習のコードを組んでみたのですが
エラーが出てしまい具体的には、アノテーションデータに 'image_path' が存在しないとの事でした。
・画像データが欲しいってことですか?
この場合jsonファイルと元画像jpegがあればモデルの学習が
出来るのですか?
実行時
Loaded dataset from 133 JSON files.
Total samples in the dataset: 0
と出るので、データセットの中身が0と出ているような気がします。
コード一応貼ります。
import os
import json
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.applications import VGG16
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# データセットのパス
json_folder_path = r'C:\Users\Desktop\機械学習'
# データセットの読み込み
def load_dataset(folder_path):
dataset = []
for filename in os.listdir(folder_path):
if filename.endswith(".json"):
file_path = os.path.join(folder_path, filename)
with open(file_path, 'r') as file:
data = json.load(file)
dataset.append(data) # appendを使用してリストに追加
# アノテーションデータを表示
print(f"Loaded dataset from {len(dataset)} JSON files.")
return dataset
# データセットの整形
def preprocess_dataset(dataset):
images = []
boxes = []
for data in dataset:
# 'image_path'が存在する場合のみ処理を行うように修正
if 'image_path' in data:
image_path = data['image_path']
label = data.get('label', None) # 'label'が存在しない場合はNoneを返す
box = data.get('box', None) # 'box'が存在しない場合はNoneを返す
if label and box:
image = cv2.imread(image_path) # OpenCVを使用して画像を読み込む
images.append(image)
boxes.append(box)
return np.array(images), np.array(boxes)
# データ拡張の設定
datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
# メインの実行部分
if __name__ == "__main__":
# データセットの読み込み
dataset = load_dataset(json_folder_path)
# データセットの整形
images, boxes = preprocess_dataset(dataset)
# データセットのサイズを確認
print(f"Total samples in the dataset: {len(images)}")
# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(images, boxes, test_size=0.2, random_state=42)
# データ拡張を適用
for i in range(len(X_train)):
img = X_train[i]
box = y_train[i]
img = np.expand_dims(img, axis=0)
box = np.expand_dims(box, axis=0)
for j, (img_aug, box_aug) in enumerate(zip(datagen.flow(img, box), datagen.flow(box, box))):
if j == 1: # 1回目のデータ拡張だけを適用
X_train = np.vstack((X_train, img_aug))
y_train = np.vstack((y_train, box_aug))
break
# モデルの構築(VGG16を利用した転移学習)
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
base_model.trainable = False
model = keras.Sequential([
base_model,
layers.Flatten(),
layers.Dense(256, activation='relu'),
layers.Dense(4) # 出力層のノード数は物体の座標情報による
])
# モデルのコンパイル
model.compile(optimizer='adam', loss='mean_squared_error')
# モデルのトレーニング
model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))
# テストデータでの評価
test_loss = model.evaluate(X_test, y_test)
print(f"Test Loss: {test_loss}")
お礼
回答ありがとうございます。以下雑感なのですが、これだけ本やサイトが乱立し、環境も進化し、ユーザの背景も千差万別、深層学習の御大のシステムもどんどん更新していくと、解説書・解説サイトにちょこちょこと綻びがでるのは仕方がないと思っています。そのことを挙げてアマゾンで批判されているのを見ることがありますが、私はあまり気にしません。それよりも目線が読者側に立っているかどうかは大きいと思っています。多分この辺でつっかえるとかの見通しです。読者としては頭の中でやっていることが大雑把にでもマッピングができて、あの辺はここだな、みたいなことがわかるようになりたいと思います(大雑把にわかりたい)。機械・深層学習はすべてpythonのライブラリ(?)の中身を見せない状態でただ(正しく)呼び出して使ってくれっというのばかりだと思います。こちらの意図(使用者)と受け側(作成者)の意図が違うということはないということは信じるしかないのですが。いつもこれ、正しく使えているのかな?という不安を払拭できません。話がそれてしまいました。すみません。