2021年 あけました!
あけましておめでとうございます!!
今年もよろしくお願い致します🙇🏻♂️
皆様にとってより良い一年になります様に😊
今年の干支は「牛」🐄
今年の目標
無理せずこつこつと!!
- 今年も xAI Meetup 盛り上げていきたい!
- オンラインでのハンズオンはハードル高いけどやってみたいですね
- もちろんふくてんもイベントしていければ!
- 産業医の先生に怒られるので、今年こそ痩せないとww
- 何か新しい特技を増やしたい
- 月一はブログ更新
今年ものんびり楽しいことをやっていけると良いな😊
2020年を振り返って
今年も残すところあと2日。
最近中々ブログも書けていないので年の最後くらいはまとめようと思います。
Private
今年も一年、家族全員大きなケガも病気もなく健康に過ごせました。
来年も健やかな一年を過ごせます様に。
ようこそプラド
子供が小さかったのでここ何台かはずっとミニバンだったのだけれど、ようやく嫁からのOKが出たので念願のSUVに!!
11月に注文したルーフラックがまだ来ないけど大事に乗ろうw
可愛い眼鏡が見つかった
大名の蒲池眼鏡でMASAHIRO MARUYAMA のアシンメトリーな眼鏡を発見!!
嫁に踏まれて他界したRaybanの眼鏡も喜んでくれてると思う(しらんけど
仕事
今の会社で働かせてもらって十数年たつのですが、社内でも他の人と違った業種なのもあり同じ会話が出来る人がいない事がすごくストレスで、数年前から自分がこの会社にいる事に違和感を感じ、2019年末から転職を考え始めていました。
ありがたいことに数社の方にお声がけ頂き転職をしようとした矢先にコロナウイルスが流行り始め一時見送りという形に・・・。
そんな中、昨年よりお手伝いさせて頂いていた次世代事業室という部署に異動になり業務内容も今までとはまた違ったものになりました。忙しいけどとても充実した日々を過ごせているのかなと。
来年も自分に出来る事はしっかりやっていこうと思います。
コミュニティ
今年の初めに「xAI Meetup」 というAIを手段としてもっと身近にもっと手軽に色々な人に利用してもらう事を目的にしたコミュニティを立ち上げました。
オンラインでのコミュニティ活動は機材や環境等を考えると中々億劫になってしまいしばらく休止していましたが、周りの皆様のご協力もあり何とかオンラインでのイベントにも参加する事が出来ました!
xTech ゆるっとLT: xAI Meetup and AR_Fukuoka
ARコンテンツ作成勉強会主催の吉永さんよりお声がけ頂き、合同でLT会を開催しました。
異分野ではあるけども、xR と AI はとても親和性が高く皆さんのお話を聞く事で様々なヒントが得られたとても素敵な会になったと思いました。
togetter.com tks-yoshinaga.hatenablog.com
www.slideshare.net www.slideshare.net
Open Source Conference 2020 Online/Fukuoka
こちらも吉永さんよりお声がけ頂き、エンジニアフレンドシティ枠で参加する事に!
xAI 運営メンバーの加藤さんと共同登壇させて頂きました。
準備段階からの加藤さんのすごさが半端なかったっすwww
エンジニアフレンドシティ福岡フェスティバル2020
こちらは、オルターブース松本さんよりお声がけ頂き、今年のテーマである「New Engineers Life」の中でも現在注目を集めている「NoCode」について対談形式でお話するというもの。
セカンドファクトリー清水さんのファシリテーションのもとあっという間の45分でした。
efc.fukuoka.jp www.youtube.com
www.slideshare.net
まとめ
今年はコロナウイルスで人と会いにくい環境になってしまった中で「新しい働き方」「新しい生活の仕方」「新しい人との接し方」など変化の多い年になったと思いますが、公私ともにオンライン/オフラインでたくさんの人に出会えた事、助けて頂いた事は本当に感謝しかありません。
コミュニティ活動も来年は少しづつ活動を再開していきたいと思っていますので来年もよろしくお願いいたしますm(__)m
それでは皆さま良いお年を…
ResNetを使ってみよう!
すごく久しぶりの投稿です。
5月から所属部署の変更があり、バタバタしてましたw(今もですが)
せっかく前回、Machine Learning のHello World をやったので、流行り(?)の ResNet を使ってみましょう。
ResNet
ResNet (Residual Network) は Microsoft Research の Kaiming He さんが2015年に考案したニューラルネットワークのモデルらしい。
2014年の画像認識の分野でトップを争う ImageNet コンペティションにおいて、1位だった GoogLeNet は 22層。ところが、翌年には GoogLeNet スゲーってなってたとこに、まさかの 152層 が出てきて(゚д゚)フォォォァァァァァァァォァオァオァオアオアォアォアア!ってなったみたいです。
ResNet の特徴
- とにかく層が深い
→ いろんな論文にも書いている通り、CNN では学習における層の深さはとても大事らしい。 - ショートカット用のルートがある
→ すごく長いニューラルネットワークの入力層に近いノードでは、色々あって勾配消失が発生し学習が止まったり、速度が低下したりしてしまうらしく、それを解決する為の方法との事。
ResNet の弱点
- すごく強いマシンが欲しい
→ 我が家のマシンは GPU GeForce Quadro P6000 / メモリ 64G ですが、それでも入力が大きいと 152層はしんどいです。 - 学習に時間がかかる
→ 11class、152層、50 Epoc とかでも5~6時間くらいかかる。
待っている間は何もしたくなくなる事もあるかもしれない。
とりあえず、メモ程度ですが学習用のコードを...。
参考にさせて頂いた無限ノック。
main.py
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf from tensorflow.keras.models import Sequential,Model from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D, Input, BatchNormalization, concatenate, AveragePooling2D, Add, SeparableConv2D from tensorflow.keras import optimizers from tensorflow.keras.callbacks import ModelCheckpoint, LearningRateScheduler, ReduceLROnPlateau, CSVLogger, TensorBoard from tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array # 好きなモデルを呼び出す import ResNet152 as resnet import seaborn as sns import csv import os import numpy as np import matplotlib.pyplot as plt import json import collections as cl import argparse import codecs from datetime import datetime def PrintLog(log): print(log,file=codecs.open('./Log/print.log','a','utf-8')) print(log) os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' physical_devices = tf.config.experimental.list_physical_devices('GPU') if len(physical_devices) > 0: for k in range(len(physical_devices)): tf.config.experimental.set_memory_growth(physical_devices[k], True) print('memory growth:', tf.config.experimental.get_memory_growth(physical_devices[k])) else: print("Not enough GPU hardware devices available") PATH = r'D:\datasets\original' train_dir = os.path.join(PATH, 'train') validation_dir = os.path.join(PATH, 'validation') # 学習用のサブディレクトリがクラスになる class_names = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'] class_names.sort() train_dirs = [] validation_dirs = [] for name in class_names: train_dirs.append(os.path.join(train_dir, name)), validation_dirs.append(os.path.join(validation_dir, name)) num_tr = [] for trdir in train_dirs: num_tr.append(len(os.listdir(trdir))) num_val = [] for valdir in validation_dirs: num_val.append(len(os.listdir(valdir))) total_train = 0 for numtr in num_tr: total_train += numtr total_val = 0 for numval in num_val: total_val += numval PrintLog("--images-----------------------") for i in range(len(class_names)): PrintLog('class : {} images'.format(class_names[i])) PrintLog(' total training {}'.format(num_tr[i])) PrintLog(' total validation {}'.format(num_val[i])) PrintLog("-------------------------------") PrintLog("Total : images") PrintLog((" training ", total_train)) PrintLog((" validation ", total_val)) num_classes = 11 channel = 3 batch_size = 11 epochs = 50 IMG_WIDTH = 1080 IMG_HEIGHT = 1080 # 写真のセンターをいい感じに切り出す def crop_center(pil_img, crop_width, crop_height): img_width, img_height = pil_img.size return pil_img.crop(((img_width - crop_width) // 2, (img_height - crop_height) // 2, (img_width + crop_width) // 2, (img_height + crop_height) // 2)) # 写真の縦の長さで正方形に切り出す def crop_max_square(pil_img): return crop_center(pil_img, min(pil_img.size), min(pil_img.size)) def preprocess(x): im = array_to_img(x) im_new = crop_max_square(im) return img_to_array(im_new) # 学習データセットに変化をつける train_image_generator = ImageDataGenerator( rescale=1./255, rotation_range=5, width_shift_range=.15, height_shift_range=.15, zoom_range=0.5, brightness_range=[0.3,1.0], preprocessing_function=preprocess ) # 学習データのジェネレータ train_image_generator.mean = np.array([123.68/255,116.779/255,103.939/255], dtype=np.float32).reshape((1,1,3)) # 必要な大きさにリサイズする train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size, directory=train_dir, shuffle=True, target_size=(IMG_HEIGHT, IMG_WIDTH), classes=class_names, class_mode='categorical') # 検証データをクロップ validation_image_generator = ImageDataGenerator(rescale=1./255, preprocessing_function=preprocess) # 検証データのジェネレータ validation_image_generator.mean = np.array([123.68/255,116.779/255,103.939/255], dtype=np.float32).reshape((1,1,3)) val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size, directory=validation_dir, shuffle=False, target_size=(IMG_HEIGHT, IMG_WIDTH), classes=class_names, class_mode='categorical') # クラスをJsonに書き出しとく dic = cl.OrderedDict() for class_index in train_data_gen.class_indices: dic[class_index] = cl.OrderedDict({"index":train_data_gen.class_indices[class_index],"name":class_index}) with open('./model/class_map.json','w') as fw: json.dump(dic,fw,indent=2) #モデルの作成 model = resnet.ResFunction(IMG_HEIGHT, IMG_WIDTH, channel, num_classes) #ラーニングレートを可変にする def lr_schedule(epoch): lr = 1e-3 if epoch > 44: lr *= 1e-6 elif epoch > 39: lr *= 1e-5 elif epoch > 34: lr *= 1e-4 elif epoch > 29: lr *= 1e-3 elif epoch > 24: lr *= 1e-2 elif epoch > 19: lr *= 1e-1 PrintLog('Next Epoc: {}, Learning rate: {}'.format(epoch + 1, lr)) return lr # ADAM オプティマイザーと binary cross entropy 損失関数を選択 # 各学習エポックの学習と検証の精度を表示するために、metrics 引数を渡す decay=1e-6 momentum=9e-1 model.compile(optimizer=optimizers.SGD(lr_schedule(0), momentum=momentum, decay=decay, nesterov=True), loss='categorical_crossentropy', metrics=['accuracy']) # modelのネットワークレイヤーを見たい場合の関数 with open('./Log/network_layer','a') as f: model.summary(print_fn = lambda x: f.write(x + '\r\n')) # モデルの学習 # ImageDataGenerator クラスの fit_generator メソッドを使用して、ネットワークを学習します。 # CallBackにモデル補正用のメソッドを指定してラーニングレートを調整する save_dir = os.path.join(os.getcwd(), 'saved_models') model_name = 'ResNetv152_model.{epoch:03d}.h5' if not os.path.isdir(save_dir): os.makedirs(save_dir) filepath = os.path.join(save_dir, model_name) checkpoint = ModelCheckpoint(filepath=filepath, monitor='val_accuracy', verbose=1, save_best_only=False) lr_scheduler = LearningRateScheduler(lr_schedule) #各エポックの結果をcsvへ保存する csv_logger = CSVLogger(filename='./Log/training.log', separator=',', append=True) callbacks = [checkpoint, lr_scheduler, csv_logger] history = model.fit( train_data_gen, epochs=epochs, validation_data=val_data_gen, validation_steps=total_val // batch_size, steps_per_epoch=total_train // batch_size, callbacks=callbacks ) #モデルを保存 model.save('./model') #Confusion_Matrixを出力 Y_pred = model.predict(val_data_gen) y_pred = np.argmax(Y_pred, axis=1) PrintLog('\r\nConfusion Matrix\r\n') cm = tf.math.confusion_matrix(val_data_gen.classes, y_pred) PrintLog(cm) sns.heatmap(cm, annot=True, fmt='d', cbar=False, cmap='Blues') plt.savefig('./model/confusion_matrix.png') # 学習結果の可視化 epochs_range = range(epochs) acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss'] plt.figure(figsize=(8, 8)) plt.subplot(1, 2, 1) plt.plot(epochs_range, acc, label='Training Accuracy') plt.plot(epochs_range, val_acc, label='Validation Accuracy') plt.legend(loc='lower right') plt.title('Training and Validation Accuracy') plt.subplot(1, 2, 2) plt.plot(epochs_range, loss, label='Training Loss') plt.plot(epochs_range, val_loss, label='Validation Loss') plt.legend(loc='upper right') plt.title('Training and Validation Loss') plt.savefig('./model/figure.png') plt.show()
ResNet152.py
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf from tensorflow.keras.models import Sequential,Model from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D, Input, BatchNormalization, concatenate, GlobalAveragePooling2D, Add, SeparableConv2D from tensorflow.keras.preprocessing.image import ImageDataGenerator def ResFunction(IMG_HEIGHT, IMG_WIDTH, channel, num_classes): def ResBlock(x, in_f, f_1, out_f, stride=1, name="res"): res_x = Conv2D(f_1, [1, 1], strides=stride, padding='same', activation=None, name=name + "_conv1")(x) res_x = BatchNormalization(name=name + "_bn1")(res_x) res_x = Activation("relu")(res_x) res_x = Conv2D(f_1, [3, 3], strides=1, padding='same', activation=None, name=name + "_conv2")(res_x) res_x = BatchNormalization(name=name + "_bn2")(res_x) res_x = Activation("relu")(res_x) res_x = Conv2D(out_f, [1, 1], strides=1, padding='same', activation=None, name=name + "_conv3")(res_x) res_x = BatchNormalization(name=name + "_bn3")(res_x) res_x = Activation("relu")(res_x) if in_f != out_f: x = Conv2D(out_f, [1, 1], strides=1, padding="same", activation=None, name=name + "_conv_sc")(x) x = BatchNormalization(name=name + "_bn_sc")(x) x = Activation("relu")(x) if stride == 2: x = MaxPooling2D([2, 2], strides=2, padding="same")(x) x = Add()([res_x, x]) x = Activation("relu")(x) return x inputs = Input((IMG_HEIGHT, IMG_WIDTH, channel)) x = inputs x = Conv2D(64, [7, 7], strides=3, padding='same', activation=None, name="conv1")(x) x = BatchNormalization(name="bn1")(x) x = Activation("relu")(x) x = MaxPooling2D([5, 5], strides=3, padding='same')(x) x = ResBlock(x, 64, 64, 256, name="res2_1") x = ResBlock(x, 256, 64, 256, name="res2_2") x = ResBlock(x, 256, 64, 256, name="res2_3") x = ResBlock(x, 256, 128, 512, stride=2, name="res3_1") # 各ブロックの繰り返し数 for i in range(7): x = ResBlock(x, 512, 128, 512, name="res3_{}".format(i + 2)) x = ResBlock(x, 512, 256, 1024, stride=2, name="res4_1") for i in range(35): x = ResBlock(x, 1024, 256, 1024, name="res4_{}".format(i + 2)) x = ResBlock(x, 1024, 512, 2048, stride=2, name="res5_1") x = ResBlock(x, 2048, 256, 2048, name="res5_2") x = ResBlock(x, 2048, 256, 2048, name="res5_3") # 一つ上の層の出力に合わせて x = GlobalAveragePooling2D()(x) #x = Flatten()(x) x = Dense(num_classes, activation='softmax', name="fc")(x) model = Model(inputs=inputs, outputs=x) return model
Hello World of Machine Learning!!
こんばんは。
会社から帰って家の事して色々してるといつもこの時間になってしまいますね。
福岡県ではコロナウイルスの感染者が 12 人に増えてしまいました💦
しっかり食べて、しっかり寝て、適度に運動して、うがい手洗いもして、出来るだけ人が集まるところは避けながらコロナに負けない生活習慣を心掛けたいです。
さて、先日までに Windows マシンの機械学習環境の構築をやっていきましたが、どうしてもやらないといけない事があって(ジャンプを読みたくて)動作確認をしてませんでしたので動作確認をしていきたいと思います。
機械学習の Hello World → MNIST の画像分類
機械学習はじめまして!な方用として良く使われる MNIST 。
様々な Hello World の中でもトップクラスの感動を得られますw
※個人的に一番感動したのは Lチカでした
MNIST
Mixed National Institute of Standards and Technology database
28x28 ピクセルの手書き数字画像のデータセットで 6,0000 個のトレーニングデータと 1,0000 個のテストデータが収容されています。
詳しく知りたい方は以下の記事で確認してみてください。
なにするの?
Tensorflow のチュートリアルにある、 MNIST の6,0000 個のトレーニングデータを学習して機械学習モデルを作成し、テストデータを用いてモデル精度を確認します。 www.tensorflow.org
学習モデルを作成する
Anaconda Prompt 等で Tensorflow-gpu 2.1.0 をインストールします。
pip install tensorflow-gpu==2.1.0
main.py
# 必要なライブラリをインポートする import tensorflow as tf from tensorflow.keras import datasets, layers, models # MNIST データセットをダウンロード (train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data() # データ数、縦px、横px、チャンネル(グレースケール:1、カラー:3) train_images = train_images.reshape((60000, 28, 28, 1)) test_images = test_images.reshape((10000, 28, 28, 1)) # ピクセルの値を 0~1 の間に正規化 train_images = train_images / 255.0 test_images = test_images / 255.0 # モデルを作成 model = models.Sequential() # 畳み込み:活性化関数 relu → 入力 x が x<=0 であれば 0 を、x>0 であれば x を返す model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) # 出力をダウンスケール model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) # 3x3x64 次元のテンソル → 576個の要素を持つ1次元のベクトルに変換 model.add(layers.Flatten()) # 全結合層 model.add(layers.Dense(64, activation='relu')) # softmax関数 → 0~1 の範囲で値を算出 model.add(layers.Dense(10, activation='softmax')) # モデルの概要を出力 model.summary() # モデルをコンパイル # optimizer:最適化アルゴリズム # loss:損失関数 (スパースなマルチクラス分類交差エントロピー関数) # metrics:評価関数 model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # 学習開始 epoc は学習回数 model.fit(train_images, train_labels, epochs=5) #モデルを保存 model.save('./model') # テストデータを用いて精度の確認 test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2) print(test_acc)
最後に
言語系の Hello World と違ってデータセットを準備したり、少し長めのコードを書く必要がありますが、実際に動かした時の感動は中々なものですね。
もっと精度を上げるには学習の回数を変えてみたり、レイヤーを変えてみたり、最適化アルゴリズムを変えてみたり、学習レートを調整してみたり、データを可視化してみるのもいいですね…。調整出来る箇所が多いですが、色々と試してみてどんな変化があるか見てみるといいかもしれません😊
Windows 10 に CUDA + cuDNN をインストール
こんばんは。
昨日に引き続き PC の設定のお話です。
今日は NVIDIA のGPU開発環境である CUDA と CUDA を使って Deep Learning の計算を高速で行うためのライブラリである cuDNN をインストールしていきますたいと思います!!
特にハマりポイントはないと思うのでさくっと入れていきます。
CUDAってなに?
CUDA(Compute Unified Device Architecture:クーダ)とは、NVIDIAが開発・提供している、GPU向けの汎用並列コンピューティングプラットフォーム(並列コンピューティングアーキテクチャ)およびプログラミングモデルである[3][4][5]。専用のC/C++コンパイラ (nvcc) やライブラリ (API) などが提供されている。なおNVIDIA製GPUにおいては、OpenCL/DirectComputeなどの類似APIコールは、すべて共通のGPGPUプラットフォームであるCUDAを経由することになる[6]。 【Wikipedia引用】
要は、NVIDIA が開発している GPU 上でプログラミングをするためのソフトウェアプラットフォームで、例えば複雑で計算量の多い処理を並列処理したい時に、GPU を使って無駄なく効率的に処理をする為のものだと思ってます。
CUDA のほかにも OpenCL っていう GPGPU(GPUによる汎用計算) があるんですが、NVIDIA の性能を最大限活かす為に CUDA が作られてるだろうから NVIDIA の GPU を利用しているのであれば、CUDA を利用する方がいいのではないかと思います。
CUDA Toolkit のダウンロード
CUDA の最新版は 10.2 ですが、Tensorflow 2.1 の環境に合わせて 10.1 をインストールしたいと思います。
以前のバージョンはこちらのアーカイブからダウンロードしましょう。
CUDA Toolkit のインストール
システム環境変数の設定 PATH
自動で PATH が追加されていることを確認します。
システム環境変数の設定 CADA_PATH
自動でCUDA_PATH と CUDA_PATH_V10_1 が追加されていることを確認します。
インストールの確認
cuDNN ってなに?
CUDA をつかって Deep Learning の計算を高速で行うためのライブラリ
様々なフレームワークに対応しています。
対応一覧
https://www.arcbrain.jp/support/NVIDIA/Deep_Learning/Frameworks/#Another_Frameworks
cuDNN のダウンロード
ダウンロードするにはユーザー登録が必要です。
必ず CUDA と同じバージョンに対応した cuDNN をインストールしてください
ダウンロードリンク
https://developer.nvidia.com/rdp/cudnn-download
cuDNN のインストール
ダウンロードした『cudnn-10.1-windows10-x64-v7.6.5.32.zip』を解凍したフォルダの中にある『cuda』フォルダを開きます。
先ほどインストールした CUDA のディレクトリに中身のフォルダ毎コピペしちゃいましょう。
CUDA Toolkit のインストールディレクトリは変更してなければ以下
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1
システム環境変数の設定 CUDNN_PATH
CUDNN_PATHを追加
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1
インストールの確認
インストール完了
お疲れさまでした。
これでCUDA と cuDNN のインストールは完了です。
Windows Tarminal に Anaconda Prompt を表示する
こんばんは。
新しい PC に機械学習環境の構築を時間のある時にぼちぼちやってます。
会社で使ってる機械学習用マシンも最近新調したので、最近同じような事を何度もやってます😅
今回は Python のインストール → Anaconda Prompt をWindows Tarminal に追加をやっていきます。
Python のインストール
こちらは Anaconda をインストールしましょう。
Anaconda
Anaconda は Continuum Analytics って会社が提供している Python と conda というパッケージマネージャーを含む Python ディストリビューション。
以下のサイトからインストーラーをダウンロードしてインストールします。
基本的にインストーラーの指示に従ってインストールすればOKです。
インストールの確認は Anaconda Prompt から以下を入力して Python のバージョンを確認で OK でしょう。
python -V
Python のライブラリをインストールしたり、仮想環境を作成したりする際に Anaconda Prompt を利用するんですが、起動するのに Windows メニューからアイコンをクリックするのが面倒なので、僕は Windows Tarminal に入れています。
Windows Tarminal
コマンドプロンプトだったり、Power Shell だったり、Cloud Shellだったり、似たようなコマンドラインツールが多いですよね。
そんなコマンドラインツール達を一括管理してくれるのが、Windows Tarminal !! これは便利ですね!!
ちなみに現在は Preview v0.9 ですが、正式版に備える予定の全機能が実装されているそう。
インストール
Windows Store からインストールしましょう。
システム要件
呼び出し
Win + R → 『wt』と入力して Enter で Windows Terminal が起動します。
ちなみにタブの所にある『∨』をクリックすると、コマンドプロンプトや Azure Cloud Shell が選択できます。
Ctrl + Shift + 数字キーで切り替え可能です。
Windows Tarminal の機能は色々あるんですが、そこは本線から外れてしまいますので適宜ggって下さい。
Anaconda Prompt を追加する
タブの所にある『∨』をクリックして Setting をクリックすると Setting.json が開きます。
※ Ctrl + ,でも OK です。
Setting.json
guid:一意のキー
name:表示名
commandline:呼び出すコマンドラインツール
// To view the default settings, hold "alt" while clicking on the "Settings" button. // For documentation on these settings, see: https://aka.ms/terminal-documentation { "$schema": "https://aka.ms/terminal-profiles-schema", "defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", "profiles": { "defaults": { // Put settings here that you want to apply to all profiles }, "list": [ { // Make changes here to the powershell.exe profile "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", "name": "Windows PowerShell", "commandline": "powershell.exe", "hidden": false }, { // Make changes here to the cmd.exe profile "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}", "name": "cmd", "commandline": "cmd.exe", "hidden": false }, { "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}", "hidden": false, "name": "Azure Cloud Shell", "source": "Windows.Terminal.Azure" } ] }, // Add custom color schemes to this array "schemes": [], // Add any keybinding overrides to this array. // To unbind a default keybinding, set the command to "unbound" "keybindings": [] }
既存の設定をコピーする
guid を変更する
一意になれば良いので、末尾の文字を変更すれば OK
変更前:"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
変更後:"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44b9}",
※16進で記載です
表示名を変更する
好きな名前にするといいと思う
変更前:"name": "Windows PowerShell",
変更後:"name": "Anaconda Prompt",
コマンドを変更する
Anaconda Prompt を呼び出す為のコマンドを変更する
① Windows メニューから Anaconda プロンプトを右クリック→その他→ファイルの場所を開く
② Anaconda プロンプトを右クリック→プロパティ
③ リンク先をコピー
④ メモ帳などに張り付けて不要な部分を削除する
⑤ ④を Setting.json の commandline に張り付け
確認してみる
Win + R → 『wt』で Windows Tarminal 呼び出し(呼び出しが楽!!)
余談
よく見ると先ほど追加した Anaconda Prompt には アイコンがないんですよね。
Setting.json で設定できるプロパティが色々ある様で、どうやら icon に何かしら設定すれば良さそうです。
プロパティ一覧
github.com
// To view the default settings, hold "alt" while clicking on the "Settings" button. // For documentation on these settings, see: https://aka.ms/terminal-documentation { "$schema": "https://aka.ms/terminal-profiles-schema", "defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", "profiles": { "defaults": { // Put settings here that you want to apply to all profiles }, "list": [ { // Make changes here to the powershell.exe profile "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", "name": "Windows PowerShell", "commandline": "powershell.exe", "hidden": false }, { // Make changes here to the cmd.exe profile "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}", "name": "cmd", "commandline": "cmd.exe", "hidden": false }, { "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}", "hidden": false, "name": "Azure Cloud Shell", "source": "Windows.Terminal.Azure" }, { "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44b9}", "name": "Anaconda Prompt", "commandline": "cmd.exe /K C:\\Users\\rupic\\anaconda3\\Scripts\\activate.bat", "backgroundImage": "C:\\Users\\rupic\\OneDrive\\画像\\anaconda.png", "colorScheme": "Solarized Light", "useAcrylic": true, "icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png", "hidden": false } ] }, // Add custom color schemes to this array "schemes": [], // Add any keybinding overrides to this array. // To unbind a default keybinding, set the command to "unbound" "keybindings": [] }
Macbookpro 入院 → 代替え機購入
こんばんは!
愛用している Macbookpro のキーボードの調子が宜しくなく久しぶりのブログです😢
どう調子が悪いかというとキー入力する際にキーを押した際にがチャタリングしている様な動作をするんです。。。
例えば『こんにちは』と入力しようとすると『こおおんにちはああ』みたいに不特定のキーが連続して入力されるような状態でコーディングはおろか通常のWEB検索すら困難ですw
これはあかんと思い Apple サポートに問い合わせたところ無償での修理をしてくれることに。
それは助かるのですが修理が完了するまでに最短で 7 営業日かかるところ、現在コロナの影響で部品が届かない事が考えられるため納期不明と…。
納期不明って💦
AzureにVM立ててiPadからーと考えましたが、メイン機として使うにはそこそこ辛いと思うのでここは代替え機を準備する事にしました。
仕様
- mouse コンピューター
- GTUNE NEXTGEAR-NOTE i7941PA1
- Windows 10 Home 64ビット
- インテル® Core™ i7-9750H
- GeForce RTX™ 2070
- 32GB PC4-19200
- 512GB M.2 SSD インテル® 660p NVMe対応
- 2TB HDD
- 17.3型 フルHDノングレア
- インテル® Wireless-AC 9560 + Bluetooth 5
ノートPCにしては珍しいメカニカルキーボードを採用しているモデルでキーの打鍵感がしっかりしていて入力しやすい。
残念ポイントはキーピッチを広く取りすぎてキー配列がちょっと使いずらいところと、メーカー製PCでは相変わらずのWindows 10 Homeなところ。
テンキー無くせばいいのになと思うけどゲーム用途と考えるとゲーム操作に影響の出ないキーはずらしちゃいますよねw
でも動作も軽快だし、使いやすいのでしばらくはこのマシンをガンガン使っていこうと思う。
せっかくGPUつんでるんだし、VR ヘッドマウント欲しいなぁ・・・。
と思いつつ、機械学習環境のセットアップしながらまたブログを書いていこうと思います。
Ink Recognizerを使ってみよう ( Cognitive Services 復習 )
こんばんは!
コロナウイルスの影響で各地のイベントは自粛ムード…
我が家は出来るだけ人が多い所を避けて、前々から嫁に頼まれてたやつをDIYしています。
さて、勉強会も中々開催できないので、時間がある時に Microosoft Azure のサービスで一番好きな Cognitive Services について不定期でのんびりブログに書いていこうと思います。
Cognitive Services
Microsoft の提供するサービスである、 Cognitive Services は人間の認知する機能の一部(見たり、聞いたり、話したり、意思決定したり、検索したり)を機械で擬似的に再現したサービスで Web API として利用できる AI パーツ。
2020.02.26 現在のサービス一覧 (27 Services ※5 preview)
- 決定:よりスマートな意思決定をすばやく行う
- Anomaly Detector(preview):発生する可能性のある問題を早期に識別
- Content Moderator:不快または望ましくない可能性のあるコンテンツを検出
- Personalizer:パーソナライズされ、優れたエクスペリエンスを提供
- 言語:非構造化テキストから意味を取り出す
- Immersive Reader(preview):音声や視覚的な合図を使用して、あらゆる能力の読み手がテキストを理解できるようにする
- Language Understanding:自然言語を解釈する機能を提供
- QnA Maker:ナレッジベースから質疑応答を、会話形式で行うことができる
- Text Analytics:センチメント、キー フレーズ、名前付きエンティティを検出
- Translator Text:60 を超えるサポート言語を検出し、リアルタイムで翻訳
- 音声:音声処理をアプリやサービスに統合する
- Speech to Text:音声を、読み取れる検索可能なテキストに書き起こす
- Text to Speech:テキストを本物のような音声に変換し、より自然なインターフェイスを実現
- Speech Translation:リアルタイムの音声翻訳をアプリに統合
- Speaker Recognition(preview):音声に基づいて人々の話を識別し、検証
- 視覚:画像、ビデオ、デジタル インク内のコンテンツを識別し、分析する
- Computer Vision:画像内のコンテンツを分析
- Custom Vision:ビジネス上のニーズに合うよう画像認識をカスタマイズ
- Face:イメージ内の人物とその感情を検出して識別
- Form Recognizer(preview):ドキュメントからテキスト、キーと値のペア、テーブルを抽出
- Ink Recognizer(preview):デジタル インクや手書き入力を認識し、一般的なシェイプの位置特定
- Video Indexer:ビデオのビジュアルとオーディオ チャネルを分析し、そのコンテンツにインデックスを設定
- 検索:World Wide Web から探しているものを見つける
- Bing Autosuggest:インテリジェントな先行入力機能が追加され、ユーザーはよりすばやくクエリを入力する
- Bing Custom Search:検索結果に広告が表示されないカスタムの検索エンジンを作成
- Bing Entity Search:名前付きエンティティを識別して分類し、それに基づいて検索結果を探す
- Bing Image Search:さまざまな画像検索オプションをアプリに追加
- Bing News Search:アプリをニュースの検索リソースに変更
- Bing Spell Check:ユーザーが単語の切れ目、スラング、名前、同音異義語、ブランドを識別して修正
- Bing Video Search:高度なビデオ検索機能をアプリに追加
- Bing Visual Search:ユーザーが画像を使用して検索
- Bing Web Search:安全で広告なしの、位置認識機能を備えた検索をユーザーが利用できるようにし、Web の検索結果、画像、ニュース、ビデオ、ビジュアルから関連情報を表示
Ink Recognizer
初回となる今回は、タイトル通り Ink Recognizer API についてです。
手書きの文字、図形、インク ドキュメントのレイアウトなどのデジタル インク コンテンツを認識できる AI サービス
ちょっと何言ってるかわかりませんね。
要は Ink Recognizer API を使用すると、アプリケーション内の手書きコンテンツを簡単に認識する事ができるんです。
あぁ、OCRかw と思われる方もいらっしゃるかと思いますが(僕もそう思いました)、タブレットPCなどにペンや手書きで書いた文字の軌跡を時間軸で並べ渡してあげる事で、図形や文字を認識してくれるというものらしいです。
できる事
手書き認識
63 の主要な言語とロケールの手書きコンテンツを認識
レイアウト認識
コンテンツを手書き領域、段落、行、単語、箇条書きに分割します。 これにより、お使いのアプリケーションでそのレイアウト情報を使用して、リストの自動書式設定や図形の配置などの追加機能を構築
図形認識
一般的な幾何学図形を認識
図形とテキストの認識
どのインク ストロークが図形または手書きコンテンツに属しているかを認識し、それらを個別に分類
価格
現在 Preview 中なので価格設定は変わる事があるかもしれませんが以下となっています。
こちら、200 ストロークの要求で 1 トランザクションでして、例えば『石橋裕太』という文字の場合、合計 37 ストロークという感じだと思います。
なので Free プランでも十分に楽しめるかと!!
実際に使ってみる
Azure Portal で Ink Recoognizer のリソースを作成
サンプルコード
こちらのコードをローカルに git clone して VS Code で開きます。
git clone https://github.com/Azure-Samples/cognitive-services-REST-api-samples cd SampleCode\cognitive-services-REST-api-samples\javascript\InkRecognition\javascript-app\src code .
あとは sample.html を開けば良いのですが、ここまで来て気づいた事としてペンで入力出来る端末がない事でしたww (Macbookなのでタッチついてない…)
とりあえず、App Service に GitHub からデプロイして iPad で動作を確認してみましょう。
動作を確認
Request
ストローク毎にポイントが時系列順で渡されてますね
{ "version": 1, "language": "ja-JP", "strokes": [ { "id": 63, "points": "48.6895,163.1115,47.3666,163.1115,46.0437,162.1193,46.0437,161.8015,45.3822,161.4630,45.3822,161.1452,46.7052,160.4682,50.0125,159.8145,55.9656,158.8198,63.2416,157.4891,73.1635,156.4943,83.0854,155.1843,91.6843,153.8511,100.2833,152.8589,105.5750,152.2026,108.2208,152.2026,109.5437,152.2026,109.5437,152.2026,108.2208,152.8589,106.8979,154.1896" }, { "id": 64, "points": "78.4552,159.1582,78.4552,158.8198,77.7937,159.1582,77.1322,160.1504,76.4708,162.4552,75.8093,166.0932,74.4864,171.3797,71.8406,177.0021,67.2104,184.2937,61.9187,191.5671,55.9656,200.1687,48.6895,206.7677,44.0593,211.7338,40.0906,215.0515,37.4447,216.3641,36.1218,216.7025,36.1218,216.0256" }, { "id": 65, "points": "65.8875,197.1895,65.8875,196.1973,65.8875,195.8588,65.8875,196.8510,65.8875,198.8406,67.2104,203.1323,68.5333,207.7625,70.5177,212.3901,73.1635,216.0256,74.4864,218.6895,75.8093,220.6765,77.1322,221.9865,77.7937,222.6427,78.4552,222.9812" }, { "id": 66, "points": "74.4864,199.8328,73.1635,198.8406,73.1635,198.8406,74.4864,198.8406,77.1322,198.1843,83.0854,197.5073,88.3770,196.5151,94.3302,195.5410,99.6218,195.2026,102.9291,196.1973,104.2520,197.1895,105.5750,198.1843,105.5750,199.8328,104.9135,201.8171,103.5906,204.1245,101.6062,206.7677,100.2833,209.4291,99.6218,211.0776,98.2989,213.7208,96.9760,215.7078,96.3145,217.0203" }, { "id": 67, "points": "85.7312,219.0073,83.0854,219.0073,82.4239,219.0073,83.0854,219.3458,85.0697,219.3458,89.7000,217.6947,96.9760,216.3641,102.9291,215.7078,104.2520,215.7078" }, { "id": 68, "points": "115.4968,171.3797,115.4968,171.0619,114.1739,170.4030,114.1739,170.0671,115.4968,169.7287,118.1427,168.7365,124.0958,168.0802,131.3718,167.4239,136.6635,166.0932,140.6322,165.0984,141.2937,164.7806,140.6322,164.7806,137.3250,164.4447,134.0177,163.4500,131.3718,161.8015,130.0489,160.1504,129.3875,158.1635,129.3875,156.8328,129.3875,156.4943,129.3875,157.1713,129.3875,159.8145,129.3875,167.0854,128.7260,174.6948,128.0645,182.9604,128.0645,191.2286,128.0645,199.1739,128.0645,205.1193,128.0645,210.0854,128.7260,213.0645,129.3875,214.3771,129.3875,214.3771,129.3875,214.0593" }, { "id": 69, "points": "131.3718,176.3458,131.3718,176.3458,130.7104,176.0254,130.0489,176.0254,129.3875,176.3458,129.3875,177.3380,128.0645,179.3250,128.0645,181.6323,125.4187,186.5984,122.1114,190.5723,118.8041,193.8719,116.1583,196.8510,114.1739,198.5021,112.8510,198.8406,112.1895,197.5073" }, { "id": 70, "points": "129.3875,175.6895,128.0645,175.0332,127.4031,174.6948,126.7416,174.6948,128.0645,174.6948,129.3875,175.6895,132.6947,177.9969,135.3406,179.9813,138.6479,181.9682,141.2937,183.6167,142.6166,184.2937" }, ...長いので省略 ] }
Response
こちらは alternates の recognizedString に候補となる文字列が帰ってきてたり、一致率が一番高い文字列がわかったり、文字のある場所が座標として帰ってきてますね
{ "recognitionUnits": [ { "alternates": [ { "category": "inkWord", "recognizedString": "右" }, { "category": "inkWord", "recognizedString": "后" }, { "category": "inkWord", "recognizedString": "谷" }, { "category": "inkWord", "recognizedString": "厄" }, { "category": "inkWord", "recognizedString": "名" }, { "category": "inkWord", "recognizedString": "古" }, { "category": "inkWord", "recognizedString": "百" }, { "category": "inkWord", "recognizedString": "召" }, { "category": "inkWord", "recognizedString": "不" } ], "boundingRectangle": { "height": 70.79000091552734, "topX": 36.119998931884766, "topY": 152.1999969482422, "width": 73.43000030517578 }, "category": "inkWord", "class": "leaf", "id": 4, "parentId": 3, "recognizedText": "石", "rotatedBoundingRectangle": [ { "x": 38.619998931884766, "y": 149.52999877929688 }, { "x": 109.52999877929688, "y": 152.1999969482422 }, { "x": 106.83000183105469, "y": 224.0399932861328 }, { "x": 35.90999984741211, "y": 221.3699951171875 } ], "strokeIds": [ 63, 64, 65, 66, 67 ] }, { "alternates": [ { "category": "inkWord", "recognizedString": "槗" }, { "category": "inkWord", "recognizedString": "楿" }, { "category": "inkWord", "recognizedString": "橎" }, ...長いので省略 ] }
まとめ
AR Fukuoka リアルタイム手書き数字認識AIを作って遊ぼうに参加してきました!
こんにちは → こんばんは!!
今日はエンジニアカフェでこちらに参加、少しだけお手伝いしてきました😊
エンジニアカフェでイベント開催すると黒板にイラストつきな紹介を書いてくれてるんですが、何気にこれ嬉しいですよね!!
今回イベントに参加しながらブログを書いているので、ちょっと長めになっちゃってます🙇🏻♂️
- イベントの雰囲気
- ディープラーニングとは
- 本日のお題
- まずはMNISTで遊んでみよう
- 画像加工処理をやってみよう
- MNISTの中身をみてみよう
- PC内臓のカメラの画像を表示する
- リアルタイム手書き数字認識を作成する
- まとめ
イベントの雰囲気
ディープラーニングとは
本日のお題
Tensorflow + Keras + Opencv を利用して、PCのカメラで撮影した手書き文字をリアルタイムで認識
- 難しい事はさておいて、ざっくり説明すると Tensorflow はゲームのハード、Keras がゲームソフト
まずはMNISTで遊んでみよう
- MNIST は機械学習のHello World!!!!
MNISTをKerasで使える形にする
import numpy as np from keras.datasets import mnist from keras.utils import np_utils #MNISTデータセット呼び出し (X_train, y_train), (X_test, y_test) = mnist.load_data() #データの正規化 X_train = np.array(X_train)/255. X_test = np.array(X_test)/255. #CNNに入れるために次元を追加 X_train = np.expand_dims(X_train, axis=-1) X_test = np.expand_dims(X_test, axis=-1) #ラベルのバイナリ化 y_train = np_utils.to_categorical(y_train) y_test = np_utils.to_categorical(y_test)
モデルの構築
from keras.layers import Input, Dense, Conv2D, MaxPooling2D from keras.models import Model from keras.layers.core import Flatten inputs = Input(shape=(28,28,1)) #入力層 conv1 = Conv2D(16, (3, 3), padding='same', activation='relu')(inputs) #畳込み層1 pool1 = MaxPooling2D((2, 2))(conv1) conv2 = Conv2D(32, (3, 3), padding='same', activation='relu')(pool1) #畳込み層2 pool2 = MaxPooling2D((2, 2))(conv2) flat = Flatten()(pool2) #全結合層に渡すため配列を一次元化 dense1 = Dense(784, activation='relu')(flat) #全結合層 predictions = Dense(10, activation='softmax')(dense1) #出力層 model = Model(inputs=inputs, outputs=predictions) #モデルの宣言(入力と出力を指定)
モデルのコンパイル、学習実行
model.compile(optimizer="sgd", loss="categorical_crossentropy", metrics=["accuracy"]) hist = model.fit(X_train, y_train, batch_size=16, verbose=1, epochs=1, validation_split=0.9)
学習結果の評価
score = model.evaluate(X_test, y_test, verbose=1) print("正解率(acc):", score[1])
モデルを保存
model.save("MNIST_test.h5")
作成されたモデルの確認
作成した学習モデルを利用して評価する
from keras.models import load_model import cv2 import numpy as np model = load_model("mnist.h5") # 学習済みモデルをロード Xt = [] img = cv2.imread("6.jpg", 0) img = cv2.resize(img,(28, 28), cv2.INTER_CUBIC) Xt.append(img) Xt = np.array(Xt)/255 Xt = np.expand_dims(Xt, axis=-1) result = model.predict(Xt, batch_size=1) print(result[0])
画像加工処理をやってみよう
OpenCVを利用して、撮影している画像をリアルタイムにKerasで認識できる形に加工する
まずはOpenCVを使って画像を表示してみる
import cv2 #Lennaを召喚する呪文:0→グレースケール、1→カラー image = cv2.imread('Lenna.png',1) #testウインドウにLennaを召喚 cv2.imshow('test',image) #何かしら操作があるまで待つ:0なので無限に待つよ cv2.waitKey(0) #ウインドウを破棄する cv2.destroyAllWindows() #Macの人は以下を入れとかないとエラー cv2.waitKey(1)
読み込んだ画像をグレーに変えてみる
*方法は簡単。2行ほど追記するだけ!
#グレースケールに変換 gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) #グレー用のウインドウを追加 cv2.imshow('gray',gray)
次は画像に資格の枠を表示する
- OpenCV は画像の左上を原点として座標を指定します。
- 以下のコードを追加
#四角を表示する cv2.rectangle(image,(50,50),(100,100),(255,0,0))
画像に文字を書く
#(窓,書き込む文字列,座標,フォント,サイズ,色,太さ,線の種類) cv2.putText(image,'Hello World',(0,30),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),1,cv2.LINE_AA)
画像を二値化→白黒反転→ブラーをかける
#大津の方法で二値化する _, th = cv2.threshold(gray,0,255,cv2.THRESH_OTSU) #白黒反転 th = cv2.bitwise_not(th) #ブラーを書ける th = cv2.GaussianBlur(th,(9,9),0)
画像をトリミング
th = th[50:150,50:150]
画像を縮小
#50 x 50 にトリミング th = cv2.resize(th,(50,50),cv2.INTER_CUBIC)
MNISTの中身をみてみよう
ここまでの内容を合体させて、先ほど利用したMNISTの中身の画像をOpenCVを利用して見てみましょう
from keras.datasets import mnist import cv2 #MNISTを画像部分だけロード (X_train,_),(_,_) = mnist.load_data() #X_trainの100番目を取得して表示 cv2.imshow('mnist',X_train[100]) cv2.waitKey(0) cv2.destroyAllWindows() cv2.waitKey(1)
PC内臓のカメラの画像を表示する
- PCのカメラにアクセスする為には、ご利用の環境によって段階を踏まないといけません。
① どのカメラを利用するか指定する
② カメラから画像を読み込む
③ カメラの画像を表示する
④ カメラを開放する
静止画
import cv2 #①カメラを指定 cap = cv2.VideoCapture(0) #②カメラから画像を読み込む ret,frame = cap.read() #③カメラの画像を表示する cv2.imshow('frame',frame) cv2.waitKey(0) #④カメラを開放する cap.release() cv2.waitKey(1) cv2.destroyAllWindows() cv2.waitKey(1)
動画
- OpenCVでは静止画をひたすら撮影→表示し続ける事で動画となるという思想なので以下で動画に対応できます
- 終了判定がないと無限に動画が表示されてしまうので、今回はキーボードのQが入力されると終了するっていうコードに、静止画コードの②と③を変更します。
while(True): ret,frame = cap.read() cv2.imshow('frame',frame) #キーボードのQが押されたら終了させる k = cv2.waitKey(1) & 0xFF if k == ord('q'):break
カメラアクセス#AR_Fukuoka#エンジニアカフェ pic.twitter.com/AIHypKtfEk
— AR Fukuoka (@ar_fukuoka) 2020年2月15日
動画の中心に四角を表示する
while (True): ret,frame = cap.read() #サイズでかいとき対策として半分にする h,w,_=frame.shape[:3] frame = cv2.resize(frame, (int(w/2), int(h/2))) #画像の形(高さ,幅,チャンネル数) h,w,_=frame.shape[:3] #y軸の中心点を取得 h_center=h//2 #x軸の中心点を取得 w_center=w//2 cv2.rectangle(frame,(w_center-71,h_center-71),(w_center+71,h_center+71),(255,0,0))
リアルタイム手書き数字認識を作成する
- ここまでくれば色々な事に応用できますね😊
- 本日の本題であるリアルタイム文字認識を作成してみましょう!!
- コツはPCのInカメラを利用した時に自分の動きが左右反転してしまうので、frame = cv2.flip(frame,1)で反転してあげると良い
完成コード
import cv2 from keras.models import load_model import numpy as np #学習モデルを読み込む model = load_model('mnist.h5') #カメラを指定する cap = cv2.VideoCapture(0) while (True): #判定用データを格納する変数 Xt = [] Yt = [] ret,frame = cap.read() #サイズでかいとき対策として半分にする h,w,_=frame.shape[:3] frame = cv2.resize(frame, (int(w/2), int(h/2))) #画像の形(高さ,幅,チャンネル数) h,w,_=frame.shape[:3] #y軸の中心点を取得 h_center=h//2 #x軸の中心点を取得 w_center=w//2 cv2.rectangle(frame,(w_center-31,h_center-31),(w_center+31,h_center+31),(255,0,0)) #トリミング(y,x)なので注意 im=frame[h_center-30:h_center+30,w_center-30:w_center+30] #グレースケール化 im=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) #二値化 _,im =cv2.threshold(im,0,255,cv2.THRESH_OTSU) #白黒反転 im=cv2.bitwise_not(im) #ブラーをかける im=cv2.GaussianBlur(im,(9,9),0) #28 x 28 にリサイズする im=cv2.resize(im,(28,28),cv2.INTER_CUBIC) Xt.append(im) Xt = np.array(Xt)/255 Xt = np.expand_dims(Xt,axis=-1) #Xtと学習したデータを比較して判定結果を返す result = model.predict(Xt,batch_size=1) #画面の反転 frame = cv2.flip(frame,1) for i in range(10): #小数点以下第二位までで四捨五入 r = round(result[0,i],2) #OpenCVで表示できる型に変換 r = "{0:0.2f}".format(r) #その数字が何かと一致する確率をセットで格納 Yt.append([i,r]) #Ytをソートする Yt = sorted(Yt,key=lambda x:(x[1])) #判定結果の上位1番目を画面上に表示する cv2.putText(frame,'1st:'+str(Yt[9]),(10,50),cv2.FONT_HERSHEY_SIMPLEX,0.8,(255,255,255),1,cv2.LINE_AA) cv2.startWindowThread() cv2.imshow("frame",frame) cv2.imshow("debug",im) key = cv2.waitKey(30) & 0xFF if key ==ord('q') : break #カメラを開放する cap.release() #フリーズ対策としてwaitKeyで挟む cv2.waitKey(1) cv2.destroyAllWindows() cv2.waitKey(1)
完成!#AR_Fukuoka#エンジニアカフェ pic.twitter.com/l5kiLUMvI3
— AR Fukuoka (@ar_fukuoka) 2020年2月15日
まとめ
- 甲斐さんの説明がめっちゃ丁寧だし分かり易いし感動!!!!
- やっぱりガッキーは可愛い
- ブログ書きながらは忙しすぎてしんどい事が判明w
- いち早くビール飲みたい
祝 xAI Meetup #1 開催しました
こんばんは!
2月7日(金)はxAI Meetupの記念すべき第一回の開催でした!
xAI Meetupって?
- 参加してくれた全員にAIという物をもっと身近に感じてもらいたい。
- もっと簡単なものだと知ってもらいたい。
- そして、目的としてのAIではなく、手段としてのAIを体験してもらいたい。
- AI開発のプロ達とAIを使う方達が交流する事で、それぞれのレイヤーの方達に気づきがあれば。
そんな想いで2019年末に立ち上げたコミュニティです。
会場の様子
タイムテーブル
セッション
既にブログにまとめて頂いているのでこちらをご覧ください🙇🏻♂️
本当に有難う御座います!!
木村さんのブログ
うしまるさんのブログ
Twitter まとめ
Welcom to xAI Meetup
石橋裕太
参加頂ける全ての人のAIに対する『わからない』を解決する事で、AIというものをもっと身近に感じてもらいたいという事、xAIでこれからやっていきたい事をお話しさせて頂きました。
Alibaba Cloud ET Brain
知念裕子さん
知念さんはAribaba Cloud のMVPアワードを受賞されており、Aribaba CloudのAIサービスであるET Brainについてご紹介頂きました!!
中でもET City Brainはリアルタイム都市データを利用した事故渋滞検出なんかできて、すごく気になるサービスだと思いました。
RC Car x AI
山田美穂さん
急遽登壇をお願いしたのにも関わらず、快諾して頂き有難う御座います🙇🏻♂️
RC Car(ラジコン)にラズパイとカメラを搭載し、人間がコントローラーで運転した内容を学習させてコースを自動走行させてみたお話しです!
めっちゃ興味あるのでうちの財務大臣に稟申しよう。。。(切実
テキスト書き起こし&読み上げLINE ボット
松本典子さん
いつも思うのは松本さんってAIに関わらず、テクノロジーを利用する人たちの理想の姿だと思うんです。
すごい技術も限られた人たちだけが使えるってのは本当の意味で普及したと言えないと思うので、こんな風にもっとみんなが自然と技術を利用できる事ができる様になれば幸せだなと思います。
www.slideshare.net
資本論 x AI
阿久沢崇さん
資本論!!!!
AI開発の導入は儲かる事を考える事が大前提です。
機械学習を利用した案件は比較的シンプルなものが多く、エンジニアの方も企画〜プロジェクトに関わっていく事で無駄な手戻りをなくす事が出来るので是非!
資本論については池上彰先生の著書がわかりやすくておすすめです!!!
www.slideshare.net
Container x AI
加藤司さん
AIの利用を想定したインフラ周り+ガ●ダムをCustom Visionで判定するお話し。
機械学習を利用したプロジェクトというと一般的にモデル開発の方に注目しがちですが、しっかりとしたインフラが基盤にあってからこそ成り立つと思います。
まとめ
記念すべき第一回開催は大盛況で幕を閉じました!!!!
今回、平日夜の勉強会開催にも関わらず、connpassでイベントをアップしてすぐに満席になり、キャンセル待ちも発生するというなんともありがたいと思うと同時に、この分野の勉強会には皆さん興味があるのだと驚きました。
次回ももっと楽しんで頂ける様にイベントを企画したいと思います!!
参加して頂いた皆様、運営、登壇して頂いた皆様、本当に有難う御座いました!
これからもよろしくお願い致します🙇🏻♂️
Fukuoka.NET #18 ~ようこそ令和2年~ 開催しました
こんばんは。
水曜、木曜と久々の高熱で死んでましたが、点滴と栄養ドリンクといっぱいの睡眠で復活しました僕ですw
年に 1 〜 2 回くらいしか風邪ひかないので久々にしんどかったです😢
本日、1月17日(金) は今年初のふくてんでした㊗️
場所はエンジニアカフェのメインホールをお借りしての開催です! fukuten.connpass.com 資料はこちら fukuten.connpass.com
あけましておめでとうございます
ふくてんはまず始めに自己紹介タイムがあります!
誰かの前で何かを話す事はすごくドキドキしますが、それが自己紹介だったとしても自身がつくし、なおかつ参加者同士の属性がわかるとお互いに話すきっかけになったりしていいですよね😊
今回初参加の方が3名ほどいらっしゃいました!
なんとも嬉しい限りです!ありがとうございます(^^)
タイムテーブル
改めてC#でできることを振り返る
オルターブース 松村さん
いまC#でできることをまとめたお話。
その中でも端末に .NET Core Runtime をインストールしなくても実行可能な
『 Self contained deployment 』
Windows Sandbox を起動し、実際に.NET Core Runtime が インストールされていない環境で動作する事を確認できる Demo は参加者の反応も良かったと思う。
www.slideshare.net
既にお兄さんのブログも公開されてますので詳細はこちらです! tsubalog.hatenablog.com
ML.NETのお話し
トヨタ自動車九州 石橋
タイトルをつけ忘れた事にセッション始まってから気づくなんて何とも申し訳ないw
『今すぐ試せる!既存のソリューションにML.NETで機械学習を実装してみよう!!』
的な感じでしょうか。
ML.NETの紹介と、Visual Studio 2019 から Model Builder を利用した画像分類の Demo をさせて頂きました😊
資料はこちら
xAI Meetup #1 はこちら! xai.connpass.com
.NET FrameworkでC# 8って使える?YESとNO!
『新規開発なのに .NET Framework 4.x? もう2020年ですよ!』と、現在.NET Framework の新規開発案件を担当されているジョニーさん😢
C# 8.0 の新機能 + .NET Framework でもC# 8.0 を利用する為に試行錯誤された内容を発表されていました!ジョニーさんすごいなぁ😲
Serverless Framework で C# を使ってみる
オルターブース 木村さん
木村さんは前職で主にperlやPHP、pythonといったいわゆるスクリプト系言語での開発をされていらっしゃったとの事で、C#はハンズオン程度で利用したことがある程度。
これからは業務で使うことが増えていくので、しっかりC#自体を勉強すると共に、最新動向もキャッチアップしていかないといけません。そのためには登壇を申し込み、それに向けて必死でネタを仕込むというのが一番です(スパルタですが)。
さすがすぎます🥰
今回は、ServerlessFramework で C# を使ってみてアレコレハマったところや、解決できたところを非常に丁寧にわかり易くご紹介して頂きました!!
www.slideshare.net
しかも誰よりも早くブログも書いて頂きました!
ありがとうございます😊
showm001.hatenablog.com
Xamarin で人生が変わった話
放浪軍師さん
というのはおいといて、
元々放浪軍師さんの努めてらっしゃった会社はゴリゴリの vb6 開発をされていたみたいで、独学でXamarin を勉強し始めたとの事。
その内容をブログに上げながら学習していたがそもそも何をどうしていいのかすらわからない。
勤めている会社と意見が合わず色々揉めてたりしている中、そんな時に軍師さんを助けてくれたのがコミュニティやブログを購読してくれてた方達だったそうで、Xamarin をどんどん覚えて行くうちに最終的には転職までしちゃいました!というサクセスストーリーでした😊
コツコツと愚直に何かができる人の事は必ず誰かが見れくれているし、認めてくれるんだなと感動しました㊗️いい話が聞けて良かったー!本当ありがとうございました!!
次回の JXUG は以下から申し込み可能です! jxug.connpass.com
まとめ
今年初めてのふくてんは参加人数は少ないながらも内容は濃かった様な気がします。っていうか自分的にすごく楽しかった!!
本当はもっと .NET を使ってらっしゃる企業さんとかあると思うので是非そんな方達ともお話ししてみたいなと思うけどそんな方にどうアプローチしていいものか、今の自分には思いつかないのでどなたかご紹介ください。
次回のふくてんは2月20日(木) 19:00 〜 開催です!
お待ちしてます😊
2020年!開けましたので…
あけましておめでとうございます!
今年もよろしくお願い致します🙇🏻♂️
皆様にとってより良い一年になります様に😊
今年の目標
- xAI Meetup を盛り上げるべく色々企画する
- 毎月ふくてんを開催
- 積極的に登壇する
- 今年は北九州でもイベント開催できたらいいな
- ブログ月3で書く
- 長女のランドセルを全力で探す
- 自転車再開して体重を減らす
色々やりたいけど楽しむ事が一番だと思うので、のんびり頑張ります😊