はじめに
みなさん、こんにちは。インプルの新入社員 てる です!
前回はたくさんの人に記事をよんでもらい、ありがとうございました。始めての投稿記事でしたが、わかりにくい点などなかったでしょうか? よければいいね・コメントもお待ちしています!
前回つくったプログラム、実は・・・。
前回作ったゴミ判別プログラム
前回はゴミ判別プログラムを作っていきました。
下の画像のように、判別して欲しいゴミの写真を読み込ませると、判別してくれるというものでした。ポケットティッシュのビニール袋なので、しっかりとプラスチックと判断していますね!

しかし、別の画像を読み込ませてみると・・・。

なんと、レシートもプラスチックと判定されてしまいました。これはよくなですね。たまたまこの画像だけプラスチックと判断された可能性もあるので、他の画像データも一気に読み込ませて試してみましょう。すると、全てプラスチック(予測スコア30%台)で判定されてしまいました・・・。これはまずい。
何が問題なの?
これについて、chatGPTに聞いてみると3つの原因を提示してくれました。

1. 学習データが偏っているは、全て100枚のデータセットを準備しているので、可能性としてはなさそうです。2. 画質や構図の違いについても、判別してほしい画像がアップで写っているので問題なさそうです。背景も騒がしい画像でないので、大丈夫そうですね。3. 画像前処理の違いも、できていたので問題なさそうです。
さらに原因を探ってみると、予測スコアの結果から次のような原因も提示してくれました。

そうやら、今回学習させたモデルでは、結果を出すときにそれも自信がなさそうで、とりあえずプラスチックのスコアが高いのでプラスチックと判別していることがわかりました。その原因として、今度は過学習を探ってみることにしました。
原因と対策
ほんとに過学習?
今回原因として考えている過学習とは、オーバーフィッティングともいい、モデルが学習データについて覚えすぎてしまい、少し違ったデータに対してうまく対応できていないことの状態を言うようです。
算数の勉強で、足し算の1+1=2というのをたくさん練習したけど、数字の違う足し算の1+2=?の問題には対応できないような状態のようですね。
さて、本当に過学習なのか・・・。学習のデータである、精度(Accuracy)と損失(Loss)のグラフを作って、chatGPTにそれをチェックしてもらうことにしました。その結果・・・、


どうやら過学習が原因だったようです。原因が突き止められました!
対策は?
この対策には、データ水増しをやってみることにしました。
データ水増しとは、1枚の画像をさまざまな向きに変えたりアップしたりして、データを水増しする方法です。早速Cursorを使って追加してもらいましょう!

指示をするだけで勝手に作ってくれます。相変わらずすごいですね・・・。
それでは、これを使って学習させていきます。そして学習させたモデルを使って、再度評価をさせてみましょう。今度はフォルダの中の画像をまとめて判別するようプログラムさせたコードで実行させてみました。そうすると・・・。

まだまだ完璧というには程遠いですが、ゴミの判別が徐々にできるようになってきました!
ですが、この後も学習方法を調節して何回か実行してみたものの、今までのように全て間違えて信頼度も低いモデルが出来上がったり、信頼度が高くて全て間違えるモデルが出来上がったり、うまくいかないことの連続でした・・・。
別のフレームワークで試してみる
Pytorch
Pytorchとは、Facebook(Meta)発のディープラーニング用フレームワークです。
これまではtensorflowというフレームワークを使用してきましたが、学習方法を変えてもうまくいかなかったので、このPytorchを使ってみることにしました。学習する教室を変えるようなイメージですね。
学習させる
それではPytorchを使って実際に学習させていきます。
ここでは PyTorch を使って、20エポック分の学習ループを回しています。学習用データをモデルに渡して、loss(損失)を計算し、optimizer.step()
で重みを更新しています。”重み”とは、学習させたデータ(ここではゴミの画像)が、どれほど学習に重要だったかを数字にしたものです。accuracy
(正解率)も毎エポック表示して、モデルの成長が分かるようにしています。
for epoch in range(20):
model.train()
running_loss = 0.0
correct = 0
total = 0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = correct / total
print(f"Epoch {epoch+1}/20 - Loss: {running_loss:.4f} - Accuracy: {accuracy:.4f}")
実行させてみる
それでは、学習させたモデルを実行させてみます。すると、予測結果がバラバラに出てきました。これはいい兆候です。画像によっては、かなり高い信頼度で予測を立ててくれている答えもあります。
📸 画像: testdata_11.jpeg
🧠 予測: cardboard (確信度: 82.66%)
--------------------------------------------------
📸 画像: testdata_76.jpg
🧠 予測: burnable (確信度: 76.99%)
--------------------------------------------------
📸 画像: testdata_62.jpg
🧠 予測: pet (確信度: 57.53%)
--------------------------------------------------
📸 画像: testdata_74.jpg
🧠 予測: pet (確信度: 95.69%)
--------------------------------------------------
📸 画像: testdata_60.jpg
🧠 予測: plastic (確信度: 45.09%)
--------------------------------------------------
📸 画像: testdata_48.jpg
🧠 予測: pet (確信度: 99.43%)
--------------------------------------------------
・・・
中には信頼度100%のものも。AIが自信を持ってペットボトルと答えています。素晴らしい!

一方で、信頼度があまり高くないもで、間違えているものもありました。ぱっと見たら、私も見間違えてしまいましたが、発泡スチロールですね、これ。間違えているものは、このように少し見間違えやすいものであったり、背景画像に反応してしまっているようなものが多かったです。その点は、まだまだ改善の余地はありそうですね。

ですが、9割以上のテストデータを正解できているようです。これはほぼ、成功と言っていいでしょう!
まとめ
さて、今回はPytorchというフレームワークを使って、ゴミ判別プログラムを改良してみました。みなさん、いかがだったでしょうか。これを他のゴミも学習させていくことができれば、さらにさまざまなゴミに対応することができそうです。よかったらぜひ皆さんも作ってみてください!
ご覧いただき、ありがとうございました。