AIが得意な「分類」とは?画像認識技術の進化を分かりやすく解説

2024年8月18日

AIによる分類
イラスト出展:OpenAI dall-e-3

初めに

こんにちは。イムでーす。今日はAIの分類機能について説明するねー。

世界一分かり易くAIについて解説します。本日はAIの分類機能について説明します。

分類機能とは

それでは分類とは何でしょうか?
分類の例として、小学校のクラス分けが挙げられます。小学校では子供の年齢に応じて学年を分けます。例えば、6歳の子は1年生、7歳の子は2年生、12歳の子は6年生というように、年齢を基準に分けることを「分類」と言います。

分類って機械で出来なかったの?

AIは分類が得意ですが、AIの登場前に機械で分類が出来なかったかと言うとそんなことはありません。コンピューターの登場前でも、機械は分類を行っていました。例えば、自動販売機では100円硬貨は受け入れますが、500円硬貨は入りませんし、1円硬貨を入れると戻ってきます。

この仕組みはシンプルです。100円硬貨より大きな硬貨は入らないように入口のサイズが100円硬貨の大きさになっています。逆に、100円硬貨より小さい硬貨は戻ってくるように出口が100円硬貨より小さくなっています。このように、分類は人間だけの特技ではなく、古くから機械でも行われていたのです。

AIが何で騒がれてるの?

では、なぜAIが注目されているのでしょうか?それは、従来は機械で簡単な分類しかできなかったところ、AIの登場によって機械が人間以上の分類能力を獲得したからです。

難しい分類ってなーに?

では、「難しい分類」とは何でしょうか?例えば、人を見分けることは実は凄く難しいことです。

人ではなく、たとえば蟻を見て、皆さんは違いがわかりますか?多くの人にとっては、蟻はみんな同じに見えるでしょう。しかし、実際には大きさや形が微妙に違うのです。これと同じで、機械では今までは人は皆同じ人に見えていて、個人個人を見分けることが出来ませんでした。

人を分類するのが難しい理由

では何故、人の分類が難しいのでしょうか?
機械や道具で人と動物を区別することは実は比較的簡単です。例えば、人形のトンネルを作り、くぐり抜けられたら人、くぐり抜けられなければ人以外と判断する方法が考えられます。しかし、この方法では個々の人を見分けることはできませんね。

では、例えば、特撮映画の特殊メイクのように石膏を使って人形を作ったらどうでしょうか?
石膏を使って人形を作ってその石膏をはめてみれば、個人個人を見分けることが出来そうです。
ですが、この方法にも問題があります。多少、太っちょになっただけで石膏がハマらず同一人物と判断出来ません。
そう。人はその時々で同じ人でも形が微妙に違うのです。だから人を見分けるというのは凄く難しいことなのです。皆さんが家族や友達をちゃんと見分けているのは実はもの凄い特技なのです。

AIによる人物の分類
出展:OpenAI dall-e-3

AIはどの様な方法で分類をしているのか?

では、AIはどのようにして分類を行っているのでしょうか?AIに詳しい方は、「AIは人の脳を模したニューラルネットワークを使っている」と答えるかもしれません。でも、正直なところ、何のことかよくわからないですよね?
ニューラルネットワーク

もう少し分かり易く教えて欲しいです。

AI専門家に怒られることを覚悟で簡単に説明すると、AIは見分けたい人の写真をたくさん撮り、その人かどうかを見分けるために、写真の画像をぼかして、回転させたり折り曲げたりして、実際の人と比較しているのです。写真の画像をぼかして、回転させたり折り曲げたりして、実際の人と比較しているのです。

画像をぼかすことで、少し太ったくらいなら同じ人に見えたりします。また、ポーズが違っていても、画像を折り曲げたり回転させたりすることで一致するかもしれません。さらに、写真を引き伸ばすことで、もっと太った状態でも一致する可能性があります。これを機械やコンピューターの力で大量に行っているのが、現在のAIなのです。

AIによる人物の分類
出展:OpenAI dall-e-3

AIの専門的な話

ちょっとー。私たちAIってそんなに簡単な仕組みじゃないと思うよ?プンプン

すみません。分かりやすく説明するために、かなり極端な例えをしました。
ここからは、コンピューターに詳しい方や興味がある方に向けて、少し専門的な話をします。

従来のプログラムの分類の仕方

それではまず、AIの前に従来のプログラムで分類する方法を説明します。
プログラムで分類を行う場合、あらかじめ人がルールを決めます。プログラムとは、つまりルールを決めることです。例えば、最初に述べた小学校のクラス分けの場合、次のようにプログラムを組みます。

Python
import random

# 生徒情報
students = [
    {"name": "田中 太郎", "age": 10},
    {"name": "佐藤 花子", "age": 9},
    {"name": "高橋 健太", "age": 11},
    # ... 省略
]

# クラス数
class_num = 3

# クラス分け
classes = [[] for _ in range(class_num)]
for student in students:
  random.choice(classes).append(student)

# 結果出力
for i, class_ in enumerate(classes):
  print(f"クラス{i + 1}:")
  for student in class_:
    print(f"- {student['name']} ({student['age']}歳)")

AIによる分類の仕方

次にAIで分類を行う方法です。AIで分類を行う場合、CNNモデルとかResNetというモデルにデータを食わせます。すると勝手に線を引いてくれます。ソースにすると以下になります。

Python
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
from torchvision import transforms
from torch.utils.data import DataLoader

# デバイスの設定
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# データセットの読み込み
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transforms.ToTensor())
test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transforms.ToTensor())

# データローダーの作成
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=False)

# ResNetモデルの構築
model = torchvision.models.resnet18(pretrained=True)
model.fc = nn.Linear(512, 10)  # 出力層の変更
model.to(device)

# 損失関数と最適化アルゴリズムの設定
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 学習の実行
for epoch in range(10):
  running_loss = 0.0
  for i, data in enumerate(train_dataloader):
    inputs, labels = data
    inputs, labels = inputs.to(device), labels.to(device)

    # 勾配の初期化
    optimizer.zero_grad()

    # 予測と損失計算
    outputs = model(inputs)
    loss = criterion(outputs, labels)

    # 誤差逆伝播
    loss.backward()
    optimizer.step()

    # 損失の記録
    running_loss += loss.item()

    if i % 2000 == 1999:
      print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
      running_loss = 0.0

# テストデータの評価
with torch.no_grad():
  total = 0
  correct = 0
  for data in test_dataloader:
    inputs, labels = data
    inputs, labels = inputs.to(device), labels.to(device)
    outputs = model(inputs)
    _, predicted = torch.max(outputs.data, 1)
    total += labels.size(0)
    correct += (predicted == labels).sum().item()
  print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))

詳しく解説しているサイトはたっくさんありますので、参考にリンク掲載致します。
https://www.sbbit.jp/article/cont1/33345

最後、まるっと別サイトにぶん投げました。
詳しく解説したらものすごーく長くなるので、別の機会に記事にしようと思います。

まあー、AI技術って、AI にぶん投げたら良きにAIがやってくれるものなので、ぶん投げ御愛嬌として下さいm( )m

わー。さいごぶんなげたーねー

本日のまとめ

まとめ
  • 分類は特定の条件などでデータを場合分けすることです。
  • AIならプログラムでは難しい高度な分類もできます
  • 人など形が常に同じでないものを分類する場合、写真を曲げたりぼかしたりして曖昧に見分けます
  • AIで分類をする場合、AIモデルにデータをぶん投げます