@yu_st

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

初心者です。pythonで画像認識アプリを制作中、その際のエラー解消方法

解決したいこと

python 初心者で画像認識アプリを制作しようと考えています。
初投稿な為、伝わりづらいと思いますがご了承ください。
主に題材は、リンゴの画像を認識アプリで傷あり色が濃い、傷ありで色が薄い、傷なしで色が薄い、傷なしで色が濃いリンゴの画像をgoogle colabでそれぞれ70枚ほど画像ファイルを作り、4つの項目に認識し判別できるアプリという定義で制作しているのですが、python初心者ながらネットを参考に色々調べて制作をしていましたが、one-hot 部分でValueError というエラーが出てしまい、その後、修正した後にライブラリーインポート部分で再度エラーが出てしまい、自分じゃどうしようもない為投稿させていただきました。

発生している問題・エラー

出ているエラーメッセージを入力
````ValueError                                Traceback (most recent call last)
<ipython-input-2-1ab0ccdfbb4b> in <cell line: 28>()
     29     img = cv2.imread("/content/drive/MyDrive/MLData/images_apple/薄い/"
     30                      + path_lightapple[i])
---> 31     b, g, r = cv2.split(img)
     32     img = cv2.merge([r, g, b])
     33     img = cv2.resize(img, (img_size, img_size))

ValueError: not enough values to unpack (expected 3, got 0)

↓こちらが元の全体のソースコードです

Google Colaboratoryとの連携

from google.colab import drive
drive.mount('/content/drive')

学習用データと検証用データの作成

# ライブラリのインポート
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Dense, Dropout, Flatten, Input
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras import optimizers

# Googleドライブのファイルパスを指定する。
path_lightapple = os.listdir("/content/drive/MyDrive/MLData/images_apple/薄い")
path_darkapple = os.listdir("/content/drive/MyDrive/MLData/images_apple/濃い")
path_hurtlightapple = os.listdir("/content/drive/MyDrive/MLData/images_apple/薄 傷")
path_hurtdarkapple = os.listdir("/content/drive/MyDrive/MLData/images_apple/濃 傷")

# 画像を格納するリストの作成
img_lightapple = []
img_darkapple = []
img_hurtlightapple = []
img_hurtdarkapple = []

# 各カテゴリの画像サイズを変換してリストに保存
img_size = 50  # 画像サイズ:50×50

# 画像の読み込みと正規化
for i in range(len(path_lightapple)):
    img = cv2.imread("/content/drive/MyDrive/MLData/images_apple/薄い/"
                     + path_lightapple[i])
    b, g, r = cv2.split(img)
    img = cv2.merge([r, g, b])
    img = cv2.resize(img, (img_size, img_size))
    img_lightapple.append(img / 255.0)  # 正規化

for i in range(len(path_darkapple)):
    img = cv2.imread("/content/drive/MyDrive/MLData/images_apple/濃い/"
                     + path_darkapple[i])
    b, g, r = cv2.split(img)
    img = cv2.merge([r, g, b])
    img = cv2.resize(img, (img_size, img_size))
    img_darkapple.append(img / 255.0)  # 正規化

for i in range(len(path_hurtlightapple)):
    img = cv2.imread("/content/drive/MyDrive/MLData/images_apple/薄 傷/"
                     + path_hurtlightapple[i])
    b, g, r = cv2.split(img)
    img = cv2.merge([r, g, b])
    img = cv2.resize(img, (img_size, img_size))
    img_hurtlightapple.append(img / 255.0)  # 正規化

for i in range(len(path_hurtdarkapple)):
    img = cv2.imread("/content/drive/MyDrive/MLData/images_apple/濃 傷/"
                     + path_hurtdarkapple[i])
    b, g, r = cv2.split(img)
    img = cv2.merge([r, g, b])
    img = cv2.resize(img, (img_size, img_size))
    img_hurtdarkapple.append(img / 255.0)  # 正規化


# 新しいセクション

# リンゴの画像をそれぞれ一つのリストに集約、及び正解ラベルを設定する。
X = np.array(img_lightapple + img_darkapple + img_hurtlightapple + img_hurtdarkapple)
y = np.array([0]*len(img_lightapple)  # 0:light apple
           + [1]*len(img_darkapple) # 1:dark apple
           + [2]*len(img_hurtlightapple) # 2:hurt light apple
           + [3]*len(img_hurtdarkapple)) # 3:hurt dark apple

#ラベルをランダムに並び変える。
rand_index = np.random.permutation(np.arange(len(X)))
X = X[rand_index]
y = y[rand_index]

# 学習データを80%、検証データを20%に分割する。
X_train = X[:int(len(X)*0.8)]
y_train = y[:int(len(y)*0.8)]
X_test = X[int(len(X)*0.8):]
y_test = y[int(len(y)*0.8):]

from keras.utils import to_categorical
import numpy as np

# サンプルデータ(適宜実際のデータに置き換えてください)
y_train = np.array([0, 1, 2, 1, 0])
y_test = np.array([2, 0, 1])

# 正解ラベルをone-hotの形にする。
y_train_one_hot = to_categorical(y_train)
y_test_one_hot = to_categorical(y_test)

print("Original labels:")
print(y_train)
print(y_test)

print("\nOne-hot encoded labels:")
print(y_train_one_hot)
print(y_test_one_hot)


モデルの定義と学習

input_tensor = Input(shape=(img_size, img_size, 3))
vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

# モデルの定義
top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(rate=0.5))
top_model.add(Dense(32, activation='relu'))
top_model.add(Dropout(rate=0.5))
top_model.add(Dense(2, activation='softmax'))

# VGG16モデルと追加層top_modelの連結。
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))

#VGG16の特徴抽出を15層までに固定。
for layer in model.layers[:15]:
    layer.trainable = False

# 損失関数と最適化関数の設定
model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(learning_rate=1e-4, momentum=0.9),
              metrics=['accuracy'])

# 訓練を実行する
history = model.fit(X_train, y_train, batch_size=64, epochs=50, validation_data=(X_test, y_test))

画像分類の結果と出力

# 画像を受け取り、名称を判別する関数
def pred(img):
    img = cv2.resize(img, (img_size, img_size))
    pred = np.argmax(model.predict(np.array([img])))
    if pred == 0:
        return "cats"
    else:
        return "dogs"

# 精度の評価
scores = model.evaluate(X_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

model.summary()

# pred関数に写真を渡して分類を予測
path_pred = os.listdir("/content/drive/MyDrive/MLData/single_prediction")
img = cv2.imread("/content/drive/MyDrive/MLData/single_prediction"
                + path_pred [1])
b,g,r = cv2.split(img)
my_img = cv2.merge([r,g,b])
plt.imshow(my_img)
plt.show()
print(pred(img))

# accuracyとlossのグラフを描画
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.plot(history.history["accuracy"], label="accuracy", ls="-", marker="o")
plt.plot(history.history["val_accuracy"], label="val_accuracy", ls="-", marker="x")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(loc="best")

plt.subplot(1, 2, 2)
plt.plot(history.history["loss"], label="loss", ls="-", marker="o")
plt.plot(history.history["val_loss"], label="val_loss", ls="-", marker="x")
plt.ylabel("loss")
plt.xlabel("epoch")
plt.legend(loc="best")

plt.show()

自分で試したこと

ネットを参考に色々調べて、まず、one-hot 部分でValueError というエラーが出てしまい、その後、修正した後に、ライブラリーインポート部分で再度エラーが出てしまい自分じゃどうしようもなく何が間違っているのかわからない状況になっていまっています。どなたか解答していただけると幸いです。皆さんよろしくお願いします。

0 likes

1Answer

エラーメッセージでググって調べてみるということはやったのでしょうか? やってないなら、是非やってみてヒットする記事を読んでください。

ググって調べてみて、ヒットした記事で該当しそうな対策を取ってみたが効果がなかったということなら、試したことを質問欄に追記してください。

2Like

Comments

  1. @yu_st

    Questioner

    回答ありがとうございます。調べた結果、修正したところ他の部分でエラーが出てしまい
    自分対策しきれなくなってしまった為、試したこと欄に再度追記させていただいたので
    よろしければ修正箇所など教えていただけると幸いです。どうかお願いします。

  2. では、今度は新しいエラーメッセージ ValueError: not enough values to unpack でググってみてください。ちなみに、 (expected 3, got 0) というのは 3 つ期待しているのに 1 つも得られなかったということです。b, g, r = cv2.split(img) でエラーが出ているなら、左辺は 3 つあるのに右辺の式からは一つも得られなかったということだと思います。

    デバッガを使ってブレークポイントを置いてそこからステップ実行して変数の中身を調べるというようなことはできますよね。デバッガが使えるならデバッグしてください。デバッガの使い方が分からなければ勉強してください。デバッグが原因究明と問題解決に一番効果的な方法で、それが今すぐできるのは質問者さんだけなのです。

Your answer might help someone💌