DEVELOPER’s BLOG

技術ブログ

無人レジ実現に挑戦 -ドーナツ金額の自動算出 Part 1- 

2019.12.24 栗木 亮輔
ニューラルネットワーク 利用事例 機械学習
無人レジ実現に挑戦 -ドーナツ金額の自動算出 Part 1- 

アクセルユニバースの栗木です。
今回実務の練習として、同じインターン生の入江君と共に模擬案件に取り組みました。
模擬案件とは、機械学習を用いることで実生活におけるどのような問題を解決できるかを考え、課題設定からデータの準備、前処理、学習、検証までの一連の作業を経験するための問題です。
今回の取り組みの中で僕達が取り組んた内容や理論を各ステップ毎に紹介していきたいと思います。記事は2部構成として、本記事では前半部分を記します。


Step. 1 課題設定

今回は無人レジの実現に挑戦します。
僕は並ぶことが苦手なので、どうにかレジの混雑を解消できないか考えました。
レジ処理は「いらっしゃいませー」「レジに商品を登録」「支払い」「ありがとうございましたー」の流れですよね。ここの「レジに商品を登録」をどうにかして効率化できれば、レジの混雑を解消でき、普及すれば、僕みたいな並びたくない族もたくさん買い物に行くはずです。


今回の目標は画像検出を用いてレジを打つことなくカメラに映すだけで合計金額を計算することとします。
画像を利用する価値を高めるためにタグが付けられない商品(食べ物)で、誰もが大好きなドーナツを対象とします。特にまだ無人化が進んでいないドーナツ屋さんの商品をトレーに載せた状態を想定しました。検出が成功すれば金額だけでなくカロリーなど+αの情報も表示が可能になりますね。


まずはじめにPart1ではひとつひとつのドーナツが何であるかを判定しました。先に結果だけお伝えすると、現時点で正答率が99%を超えていて今後の検討も楽しみです。


実際にシステムを作っていきます。まずは学習データを用意していきましょう。

Step. 2 学習データの準備

早速7種類のドーナツを購入し撮影を行いました。
角度や裏表を変えつつそれぞれ100枚の写真を撮りました。以下に写真の一例を示しておきます。
ちなみに撮影後においしく頂きました。^^

Donuts また、それぞれのドーナツの名前(ラベル)は以下とします。
8枚目の写真は物体検出する際にアノテーションされたデータが必要となるのでそのためのものです。アノテーションに関する詳細は後半の記事で説明したいと思います。


1.エンゼルフレンチ
2.ダブルチョコレート
3.エンゼルクリーム
4.ポン・デ・リング
5.オールドファッションハニー
6.ストロベリーカスタードフレンチ
7.チョコファッション
8.複数ドーナツ(物体検出用)

Step. 3 画像データの読み込み

学習のための画像データが準備出来たので、学習に備えてデータの読み込みとサイズを統一するためリサイズを行います。
今回はGoogle Colabratoryを使用するため、Google Driveに先程の画像をアップロードし以下のようにマウントすることでGoogle Colabratoryからデータにアクセス出来るようにします。
Google DriveにはDonuts Filesディレクトリを作成し、そこに先程の画像のうち複数ドーナツ以外の7種類の画像をディレクトリ毎にまとめてあります。(複数ドーナツの画像は後半で扱います)


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

次にDonuts Files内の画像をディレクトリごとに読み込みリサイズを行います。

#必要なライブラリのimport
import os
import numpy as np
import glob
import cv2
from keras.utils import np_utils

IMAGE_SIZE = 100 #リサイズ後のサイズ指定

# Donuts Filesディレクトリから画像の読み込み及びリサイズ
def get_data_and_label(path):
  X = []
  Y = []
  label = {}
  i = 0
  for dir_name in os.listdir(path):
      label[dir_name] = i
      for file_path in glob.glob(path+'/'+dir_name+'/'+'*'):
        img = cv2.imread(file_path)
        img = cv2.resize(img,(IMAGE_SIZE,IMAGE_SIZE)) #100*100にリサイズ
        X.append(img)
        Y.append(i)
      i += 1
  X = np.array(X)
  Y = np.array(Y)
  X = X.astype('float32')
  X = X / 255.0 #RGBの値を正規化
  Y = np_utils.to_categorical(Y, len(label)) #One-hotベクトルの作成
  return X, Y, label

X, Y, label = get_data_and_label('drive/My Drive/Donuts Files')

これでデータの読み込みとリサイズは完了です。最後に精度の評価用にデータの分割を行います。

from sklearn.model_selection import train_test_split

# 学習データのうち20%を検証データにする
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.20)

データの準備が出来たので、実際にモデルの学習と精度の検証を行いましょう。
最終目標は物体検出を行うことですが、前半である本記事ではまず1枚の画像に対して1つのラベルの予測を行う画像認識を実装しどの程度分類出来るか確認します。

Step. 4 モデル構築&学習

今回の問題は画像認識なので、モデルはCNN(畳み込みニューラルネットワーク)を使用します。
CNNの詳細については多くの方が記事にされているのでそちらを参考にして下さい。
簡単に説明すると、CNNは畳み込み層、プーリング層、全結合層から成り立っており、まず畳み込み層では複数のフィルタを使用して画像を畳み込むことでエッジやパターンなどの特徴を抽出します。
次にプーリング層でデータサイズを減らしつつ平行移動などの処理に対するロバスト性を獲得し、最後に通常のディープラーニングと同様の全結合層でこれまでに抽出した特徴とラベルの関係性を学習します。
CNNは2012年の画像認識コンペ(ILSVRC)で圧倒的な成績を残して注目されて以来、急速に発展を続けているので是非色々と調べてみて下さい。
それではKerasを用いてモデル構築を行いましょう。KerasはバックエンドでTensorFlowを利用するディープラーニングライブラリラッパーです。

#必要なライブラリのimport
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPool2D
from keras.optimizers import RMSprop  #最適化手法としてRMSpropを使用

# モデルの定義
model = Sequential()

model.add(Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)))
model.add(MaxPool2D((2, 2), padding='same'))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(MaxPool2D((2, 2), padding='same'))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(MaxPool2D((2, 2), padding='same'))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dense(len(label), activation='softmax', name='predicton'))

Kerasではモデルの構造をmodel.summary()から以下のように簡単に確認できるので非常に便利ですね。

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 100, 100, 32)      896       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 50, 50, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 50, 50, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 25, 25, 64)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 25, 25, 128)       73856     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 13, 13, 128)       0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 21632)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 64)                1384512   
_________________________________________________________________
predicton (Dense)            (None, 7)                 455       
=================================================================
Total params: 1,478,215
Trainable params: 1,478,215
Non-trainable params: 0
_________________________________________________________________

それでは最後にモデルの学習と評価を行います。

# モデルのコンパイル
model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(),
              metrics=['accuracy'])

#パラメータの指定
batch_size = 64
epochs = 20

# 学習
history = model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size)

# 検証データによるモデルの評価
print(model.evaluate(X_test, y_test))

最終的なlossと正解率は以下のようになりました。

loss = 0.02750563397655182
accuracy = 0.9927007299270073

正答率が99%を超えており非常に高いスコアとなりました。
今回はかなり問題設定が単純だったことと、本来は同じ種類であっても多くのドーナツを用意すべきところを1つのドーナツから学習データを作成したことがこのスコアにつながったと考えられます。

終わりに

ドーナツ検出に向けて前半である本記事では、目的を設定し画像を収集するところから単純な画像認識を行うところまでご紹介しました。
最近は画像認識を簡単に実装出来るので、是非身近なものなどの分類に挑戦してみて下さい。


さてドーナツの分類は高精度で行えることが確認できたので、後半はいよいよレジの無人化という課題に向けて検出に挑戦しようと思います。
後半では物体検出のアルゴリズムの概要や検出の様子を紹介したいと考えているので、後半もよろしくお願いします!


アクセルユニバース株式会社(以下当社)では、人が対応している業務を画像認識、音声認識、文字認識等を活用して効率化する機械学習ソリューション開発をおこなっています。
今回挑戦している無人レジだけではなく、人と会話するかのようにシステムに問合せができるチャットボットや、カメラの前の人が誰であるか判別できる認証システムも検討しております。

  • 機械学習でどんな事ができるのか興味がある
  • 課題と感じている業務がある
  • 効率化したい業務がある


上記のような方はぜひ問い合わせページにご連絡ください。


Twitter・Facebookで定期的に情報発信しています!

関連記事

通信をすべてNAT Gatewayを通していませんか?棚卸しによる70%のコスト削減に成功!

目次 背景 原因究明 解決策 結果 背景  AUCでは、SRE活動の一環として、AWSコストの適正化を行っています。 (技術ブログ『SRE:コスト抑制のための異常値検知機構の実装』) コスト適正化における課題は、大きく分けて下記の4つです。 ①コストは月末にチェックしており、月中でコストが急激に上昇した場合発見が遅れてしまう。 ② 不要なリソースが放置されていたり、新たなリリースによって生じたコストを確認していない。 ③ AWSが提供するベスト

記事詳細
通信をすべてNAT Gatewayを通していませんか?棚卸しによる70%のコスト削減に成功!
AWS SRE 利用事例
SRE:コスト抑制のための異常値検知機構の実装

目次 実装前の課題 採用した技術と理由 実装した内容の紹介 改善したこと(抑制できたコスト) 実装前の課題  SRE(Site Reliability Engineering:サイト信頼性エンジニアリング)とは、Googleが提唱したシステム管理とサービス運用に対するアプローチです。システムの信頼性に焦点を置き、企業が保有する全てのシステムの管理、問題解決、運用タスクの自動化を行います。 弊社では2021年2月からSRE活動を行っており、セキュリ

記事詳細
SRE:コスト抑制のための異常値検知機構の実装
AWS SRE 利用事例
AWSを利用した弊社の開発環境

目次 AUCの使用ツール GitHub、CircleCI使用までの流れ AWSの構成図 まとめ AUCの使用ツール 弊社ではGitHubとCircleCIの2つのツールを利用し、DevOpsの概念を実現しております。 DevOpsとは、開発者(Development)と運用者(Operations)が強調することで、ユーザーにとってより価値の高いシステムを提供する、という概念です。  開発者は、「システムへ新しい機能を追加したい」  運用者は、「システムを

記事詳細
AWSを利用した弊社の開発環境
利用事例
機械学習で採用予定人数を予測する。狙い目企業はどこ?

2022年卒大学生の皆さん! コロナウイルスが流行していることで就活にどういう影響があるのか、とても不安ですよね。 今回は業界ごとに採用人数を予測し、「どの業界が狙い目なのか」機械学習を使った分析手順を紹介します! 目次 概要 手順 今後の課題 1.概要 データセットの内容 分析対象の7業界・各4企業 化粧品 電子機器 商社 不動産 金融 サービス IT・情報 説明変数と目的変数 特徴量 年初の株価、決算報告書提出翌日の株価、一株あたりの純資産額、従業員数

記事詳細
機械学習で採用予定人数を予測する。狙い目企業はどこ?
利用事例 機械学習

お問い合わせはこちらから