【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}")