データサイエンティスト(仮)

元素粒子論博士。今はデータサイエンティスト(仮)。

ヒアリチェッカーを作ってみた:とにかく出してみる

(注)中身はまだ非公開

導入

最近、日本に危機が迫っています。
f:id:tekenuko:20170723113706j:plain
そう、ヒアリです。

ヒアリは在来種と違った繁殖方法を持ち、毒性もあるので、あれよあれよという間に我々の周りに広がっていく可能性もあります。その場合、ヒアリをきちんと見分けられないといつ痛い目にあってもおかしくありません。

備えたい。

というわけでヒアリチェッカーを作ろうと思いました。

類似物

作ろうと決意したものの、ヒアリの画像を検索して

  • どれがヒアリだ~
  • 画像集まんないな~
  • 手間かかるな~

などとうだうだしてたら以下が先にリリースされてしまいました。
alfredplpl.softether.net

くやしい。こっちはまだアプリ化してないよ。

というわけで、いろいろ精緻化する前に、現時点でできているもので判別させてみたものを出してしまおうと思いました。

ヒアリチェッカーの中身について

中身については、いったん非公開としておきます。非公開とするほど素晴らしいものではないんですが、カイシャーで使うかもしれないので。

画像判別例

先ほどのヒアリ画像を作ったヒアリチェッカーに入力した結果は以下になります。
f:id:tekenuko:20170723115805p:plain

(この画像から、まだJupyterに書きおこしたものしかないのがバレバレ(笑))
とりあえず、簡易的にある閾値を超えたらヒアリとするようにしていますが、このヒアリヒアリと判別されたようです。

別のアリ(種類は不明)も入力してみます。
f:id:tekenuko:20170723115904p:plain
f:id:tekenuko:20170723120407p:plain

シロアリ(っぽいアリ)の精度は若干落ちますが、ヒアリでないアリはヒアリでないと判別されています*1。間違えやすいアリについてはまだ試していませんので、性能としては未知数ですが、わかりやすいものは判別できるのではないでしょうか。

おまけ

twitterで、ヒアリかもしれないという方がいたので、こちらでもチェックしてみます。不適切でしたら削除します。
f:id:tekenuko:20170723121246p:plain

確かにヒアリかもしれない。

*1:実は、一番最初のプロトタイプはシロアリがうまく判別できていませんでした。少し工夫してマシにしました。

KerasでDeep Learning:KerasでMNISTデータを扱ってみる

導入

前回は人工データを用いたネットワーク構築について紹介しました。
tekenuko.hatenablog.com
今回は、異なるデータ(MNIST)に対してモデルを作成してみます。

MNIST

MNISTとは、「Mixed National Institute of Standards and Technology database」の略で、手書きの数字(0~9)に正解ラベルが与えられているデータセットです。
MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges
無料で入手かつ手軽に分析できるデータセットなので、機械学習(特に画像処理系)ではよく用いられます。
手書き文字は28ピクセル×28ピクセルの画像で与えられており、データ数は学習:テスト = 60000枚 : 10000枚です。

Kerasでは、MNISTをダウンロードするメソッドが実装されているので、それを利用して中身を少し覗いてみます。

# 必要なライブラリのインポート
import keras
from keras.datasets import mnist
# Jupyter notebookを利用している際に、notebook内にplot結果を表示するようにする
import matplotlib.pyplot as plt
%matplotlib inline

#Kerasの関数でデータの読み込み。データをシャッフルして学習データと訓練データに分割
(x_train, y_train), (x_test, y_test) = mnist.load_data()

#MNISTデータの表示
fig = plt.figure(figsize=(9, 9))
fig.subplots_adjust(left=0, right=1, bottom=0, top=0.5, hspace=0.05, wspace=0.05)
for i in range(81):
    ax = fig.add_subplot(9, 9, i + 1, xticks=[], yticks=[])
    ax.imshow(x_train[i].reshape((28, 28)), cmap='gray')

f:id:tekenuko:20170705202736p:plain
なんというか、温かみのある文字たちが出現します。

データ加工

次に、MNISTデータを加工します。ここでは、28ピクセル×28ピクセルのデータを28×28=784次元のベクトルに変換し、ベクトルの成分を0~1の範囲に正規化します。

# 2次元データを数値に変換
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
# 型変換
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# 255で割ったものを新たに変数とする
x_train /= 255
x_test /= 255

Deep Learningによる画像データの解析では、畳み込みニューラルネットワーク(Convolutional Neural Network : CNN)がよく知られており、その場合は28ピクセル×28ピクセルのデータを行列として入力します。今回は、よりプリミティブなネットワークを作る予定なので、ベクトルデータに変換しています。

また、ベクトルの成分を0~1に変換していますが、これは必須かどうかちょっと判断に迷う操作です。正規化をしないで学習もしてみたのですが、今回は精度が全然出ない結果になりました。しかしながら、別のデータセットや(Kerasのバックエンドで動いているTensorflowをはじめとした)別フレームワークでは必ずしも精度が出ないというわけでもなかったからです。この挙動に関しては、まだ要因を分解できていないため、ここでは深く立ち入らず、Kerasのチュートリアルの通りにデータを正規化して話を進めます。

次に、目的変数(0~9の10種類のラベル)の加工を行います。Kerasでは、0と1が成分となっている配列でラベルを表示する必要があります。そのため、加工に必要なライブラリをインポートし、処理をします。

# one-hot encodingを施すためのメソッド
from keras.utils.np_utils import to_categorical
# クラス数は10
num_classes = 10
y_train = y_train.astype('int32')
y_test = y_test.astype('int32')
# one-hot encoding
y_train = to_categorical(y_train, num_classes)
y_test =  to_categorical(y_test, num_classes)

ここで、one-hot encodingは以下のような変換を数値に対して施しています。

0 → [0,0,0,0,0,0,0,0,0,0]
1 → [0,1,0,0,0,0,0,0,0,0]
2 → [0,0,1,0,0,0,0,0,0,0]
3 → [0,0,0,1,0,0,0,0,0,0]
...
9 → [0,0,0,0,0,0,0,0,0,1]

また、num_classes = 10と明示的に指定しておくのが安全です。なぜなら、学習データとテストデータをランダムに分割しているので、分け方によってはどちらかのデータセットのクラス数が10にならない可能性があるためです。

これでデータの準備は完了です。

ネットワーク構築

前回紹介した手法の一つ、Sequentialモデルで作成します。

# 必要なライブラリのインポート、最適化手法はAdamを使う
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import Adam

# モデル作成
model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))

基本は全結合で活性化関数はReLUですが、過学習防止のため、Dropoutという操作もしています。これは、学習の最中にネットワークのノードをランダムに削ることで、過学習が進みすぎるのを防止するような仕組みです。0.2という引数は20%削ることを意味しています。

model.summary()でサマリを見てみます。

model.summary()
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 512)               401920    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________

上からネットワークの種類やノード数、パラメータ数などが順繰り表示されます。わかりやすい。

別の可視化

以下のように書いても、ネットワークの情報を表示できます。ただし、keras.utils.vis_utils を使用するためにはgraphvizというソフトウェアが別途必要なため、Macユーザは例えばbrew installで、Linux(Ubuntuとか)ユーザはapt-get installであらかじめ入れておいてください。

from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot

SVG(model_to_dot(model).create(prog='dot', format='svg'))

f:id:tekenuko:20170705205955p:plain

学習、テスト

実際に学習をしてみましょう。学習結果はhistoryという変数で残しておきます。model.evaluate()でテストデータに対してAccuracy(正答率)を計算し、それも別途出力します。

# バッチサイズ、エポック数
batch_size = 128
epochs = 20

model.compile(loss='categorical_crossentropy',
              optimizer=Adam(),
              metrics=['accuracy'])

history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1,
                    validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 7s - loss: 0.2521 - acc: 0.9244 - val_loss: 0.1085 - val_acc: 0.9652
Epoch 2/20
60000/60000 [==============================] - 7s - loss: 0.1044 - acc: 0.9680 - val_loss: 0.0889 - val_acc: 0.9707
Epoch 3/20
60000/60000 [==============================] - 7s - loss: 0.0714 - acc: 0.9777 - val_loss: 0.0621 - val_acc: 0.9811
Epoch 4/20
60000/60000 [==============================] - 7s - loss: 0.0562 - acc: 0.9822 - val_loss: 0.0752 - val_acc: 0.9773
Epoch 5/20
60000/60000 [==============================] - 7s - loss: 0.0457 - acc: 0.9848 - val_loss: 0.0627 - val_acc: 0.9817
Epoch 6/20
60000/60000 [==============================] - 7s - loss: 0.0384 - acc: 0.9872 - val_loss: 0.0602 - val_acc: 0.9828
Epoch 7/20
60000/60000 [==============================] - 7s - loss: 0.0326 - acc: 0.9892 - val_loss: 0.0661 - val_acc: 0.9820
Epoch 8/20
60000/60000 [==============================] - 7s - loss: 0.0304 - acc: 0.9894 - val_loss: 0.0658 - val_acc: 0.9816
Epoch 9/20
60000/60000 [==============================] - 7s - loss: 0.0267 - acc: 0.9914 - val_loss: 0.0691 - val_acc: 0.9820
Epoch 10/20
60000/60000 [==============================] - 7s - loss: 0.0276 - acc: 0.9905 - val_loss: 0.0719 - val_acc: 0.9796
Epoch 11/20
60000/60000 [==============================] - 7s - loss: 0.0218 - acc: 0.9925 - val_loss: 0.0698 - val_acc: 0.9825
Epoch 12/20
60000/60000 [==============================] - 7s - loss: 0.0232 - acc: 0.9920 - val_loss: 0.0841 - val_acc: 0.9786
Epoch 13/20
60000/60000 [==============================] - 7s - loss: 0.0206 - acc: 0.9929 - val_loss: 0.0979 - val_acc: 0.9790
Epoch 14/20
60000/60000 [==============================] - 7s - loss: 0.0211 - acc: 0.9930 - val_loss: 0.0775 - val_acc: 0.9803
Epoch 15/20
60000/60000 [==============================] - 7s - loss: 0.0189 - acc: 0.9938 - val_loss: 0.0726 - val_acc: 0.9832
Epoch 16/20
60000/60000 [==============================] - 7s - loss: 0.0174 - acc: 0.9941 - val_loss: 0.0820 - val_acc: 0.9823
Epoch 17/20
60000/60000 [==============================] - 7s - loss: 0.0159 - acc: 0.9944 - val_loss: 0.0819 - val_acc: 0.9820
Epoch 18/20
60000/60000 [==============================] - 7s - loss: 0.0161 - acc: 0.9946 - val_loss: 0.0776 - val_acc: 0.9831
Epoch 19/20
60000/60000 [==============================] - 7s - loss: 0.0195 - acc: 0.9935 - val_loss: 0.0818 - val_acc: 0.9819
Epoch 20/20
60000/60000 [==============================] - 7s - loss: 0.0141 - acc: 0.9952 - val_loss: 0.0751 - val_acc: 0.9826
Test loss: 0.0751098209593
Test accuracy: 0.9826

テストデータのAccuracyが98%を超えるんですか。そんなに凝ったネットワークでもないのにすごいですね。

可視化

Accuracyとloss functionをepoch数でプロットしてみましょう。

#Accuracy
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
#loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

f:id:tekenuko:20170705210818p:plain
f:id:tekenuko:20170705210845p:plain
学習データに関しては、学習を進めると精度がどんどん良くなっている様が見えます。一方で、テストデータに関しては、(十分良いのですが)あるepochからloss functionが微妙に増加するような振舞いをしています。過学習(今あるデータに特化しすぎて未知のデータに対する性能が落ちる)の傾向が見えているようです。

Early stopping

過学習を防ぐ方法の一つとして、予測性能が下がる前に学習を打ち切る、というものがあります。こういった方法をEarly stoppingといいます。検証用データ(validation data)を学習データの中からいくらか選び、学習した結果をその検証用データに適用し、精度やloss functionが劣化したら学習を打ち切ります(すぐに打ち切るか少し様子見をするかはオプションで指定できます)。

実際にコードを動かしてみます。

# 必要なライブラリのインポート
from keras.callbacks import EarlyStopping

# モデルの訓練
history_ES = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1,
                    validation_split=0.1,
                    callbacks=[early_stopping])

今回は、以下のように途中で学習が止まります。

Train on 54000 samples, validate on 6000 samples
Epoch 1/20
54000/54000 [==============================] - 5s - loss: 0.0073 - acc: 0.9975 - val_loss: 0.0080 - val_acc: 0.9980
Epoch 2/20
54000/54000 [==============================] - 5s - loss: 0.0078 - acc: 0.9978 - val_loss: 0.0264 - val_acc: 0.9938
Epoch 00001: early stopping

Accuracyとloss functionをepoch数でプロットすると以下のようになります。

#Accuracy
plt.plot(history_ES.history['acc'])
plt.plot(history_ES.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
#loss
plt.plot(history_ES.history['loss'])
plt.plot(history_ES.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

f:id:tekenuko:20170705211341p:plain
f:id:tekenuko:20170705211359p:plain

まとめとNext Step

今回はMNISTという画像データに対してネットワーク構築をしてみました。あまり複雑なネットワークでないにも関わらず、高い性能をもつものができたのでした。

次回は、より画像データの処理に強みを持ったネットワークの構築を目指していきます。やっとCNNの出番ですね。

KerasでDeep Learning:とりあえずネットワークを組んでみる

導入

前回はKerasを導入しました。
tekenuko.hatenablog.com

今回は、実際にネットワークを組んで学習をさせてみようと思います。簡単すぎるような気がしますが一歩ずつ…。

データセット

人工的に乱数を振って作成したものを用います。

import numpy as np
# 784次元のベクトルを1000個生成、成分は一様乱数
data = np.random.random((1000, 784))
# 0-9の数値をランダムに1000個生成
labels = np.random.randint(10, size=(1000, 1))

Kerasでは、ラベルはone-hot encoding(一つの成分が1で、他は0の列)で表す必要があります。必要なメソッドインポートして変換します。

from keras.utils.np_utils import to_categorical
labels = to_categorical(labels, 10) 

ネットワーク作成

実際にちょこざいなネットワークを構築してみます。Kerasのよいところの一つに、ネットワーク作成部分が容易かつ分かりやすいということがあります。書き方ですが、大きく2通りあるようなので、同じネットワークと2通りの方法で書いてみます。

Sequentialモデル

入力層から順繰りレイヤーを足していくような書き方をするものです。まず、今回必要なライブラリをインポートします。

from keras.models import Sequential
from keras.layers import Dense, Activation

model = Sequential()で初期化し、model.add()でネットワークを足していきます。

model = Sequential()
model.add(Dense(64, activation='relu', input_shape = (784, )))
model.add(Dense(64, activation='relu'))
model.add(Dense(10, activation='softmax'))

ネットワークの次元や活性化関数は以下です。

  • 1層目:全結合、入力784次元、出力64次元、活性化関数ReLU
  • 2層目:全結合、入力64次元、出力64次元、活性化関数ReLU
  • 2層目:全結合、入力64次元(たぶん)、 出力10次元、活性化関数SoftMax

活性化関数は以下のものを使用できます。

  • softplus
  • softsign
  • relu
  • tanh
  • sigmoid
  • hard_sigmoid
  • linear

より高度な活性化関数は、Advanced Activations Layers - Keras Documentationを参照ください。例えば、leaky_reluを使いたい場合は

from keras.layers.advanced_activations import LeakyReLU
leaky_relu = LeakyReLU()

などとしてactivation=leaky_reluとします。

モデルのコンパイルをmodel.compileで行います。

model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

暗にいくつかデフォルトの引数を使っていますが、指定できるオプションは例えば以下です。

  • loss : 損失関数
    • mean_squared_error : 二乗誤差
    • mean_absolute_error : 絶対誤差
    • mean_absolute_percentage_error, make : 正解とのズレ(絶対値)の割合
    • mean_squared_logarithmic_error, msle : 正解とのズレ(二乗誤差)の割合
    • squared_hinge : マイナスのところは0, プラスは二乗誤差
    • hinge : マイナスのところは0, プラスは絶対値
    • binary_crossentropy : logloss
    • categorical_crossentropy : マルチクラスlogloss
    • sparse_categorical_crossentropy : スパースラベルを取る categorical_crossentropy
    • kullback_leibler_divergence, kld : 分布の距離(的なもの)
    • poisson : 予測-正解*log(予測)の平均
    • cosine_proximity : 予測と正解間のコサイン近似の負の平均
  • optimizer : 最適化関数
    • SGD
    • RMSprop
    • Adagrad
    • Adadelta
    • Adam
    • Adamax
    • Nadam
    • TFOptimizer
  • metrics : 評価指標
    • 一般にはmetrics=['accuracy']を使う

細かいのは他にもありますが、それはModelクラス (functional API) - Keras Documentationを参照ください。

学習はmodel.fit()で行います。

model.fit(x = data, y = labels)

オプション(一部)は以下です。より詳細はModelクラス (functional API) - Keras Documentationを参照ください。

  • x : 説明変数
  • y : 目的変数
  • batch_size : ミニバッチのサイズ
  • epochs : 同じデータで何回繰り返し学習するか、デフォルトは10
  • validation_split : 各epochで学習データの何パーセントをvalidation用データにするか

実行すると以下のものが出力されます。

Epoch 1/10
1000/1000 [==============================] - 0s - loss: 2.7473 - acc: 0.0970     
Epoch 2/10
1000/1000 [==============================] - 0s - loss: 2.3096 - acc: 0.0920     
Epoch 3/10
1000/1000 [==============================] - 0s - loss: 2.3065 - acc: 0.1100     
Epoch 4/10
1000/1000 [==============================] - 0s - loss: 2.2989 - acc: 0.1260     
Epoch 5/10
1000/1000 [==============================] - 0s - loss: 2.2863 - acc: 0.1310     
Epoch 6/10
1000/1000 [==============================] - 0s - loss: 2.2813 - acc: 0.1290     
Epoch 7/10
1000/1000 [==============================] - 0s - loss: 2.2456 - acc: 0.1590     
Epoch 8/10
1000/1000 [==============================] - 0s - loss: 2.2265 - acc: 0.1990     
Epoch 9/10
1000/1000 [==============================] - 0s - loss: 2.3623 - acc: 0.2040     
Epoch 10/10
1000/1000 [==============================] - 0s - loss: 2.2957 - acc: 0.2300

はい。。乱数を生成させて作ったデータなので、精度もへったくれもないです。

Functional API

こちらは、浅いネットワーク層の結果を次のネットワーク層の引数に渡してつないでいくイメージです。Chainerに近いかも。

# 必要なライブラリ
from keras.layers import Input, Dense
from keras.models import Model

こちらの場合は、以下のようにModelメソッドにin/outを入れるように書きます。

inputs = Input(shape=(784,))
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)
model = Model(inputs=inputs, outputs=predictions)

あとはSequentialの場合と同様、Modelのcompile、fitメソッドを使ってモデルをコンパイルして学習しますが、似たような感じなので省略します。ただし、こちらのfitメソッドのepoch数のデフォルトは1のようです。

感想

あまりコードを書かなくてもネットワークを構築して学習できるため、非常に便利だなと感じました。とりあえずざっくり分析したいときはKerasを使うと手早く分析できそうです。細かいことが気になったときはどうなのかはおいおい調べていくということで。

Next Step

今回はちょこざいなデータを使いましたが、もう少しまともなデータを使って勉強していこうと思います。

KerasでDeep Learning:導入

導入

年齢を重ねるにつれて、能力が落ちてきて危機感を感じています。こまめに努力しようと思います。

最近、Deep Learningを使うふりをしていて、申し訳程度にChainerを使っています。Chainerも書きやすいのですが、日本人ユーザがメインなので、Tensorflowなどと比較するとナレッジの蓄積具合がどうしても気になってしまいます。ただし、Tensorflowは慣れると良いらしい(同僚談)のですが、ちょっと導入ハードルが高いなあと二の足を踏んでいました。

と思っていたら、KerasというTensorflowやTheanoをバックエンドとしたフレームワークが良さそうとの噂(またまた同僚談)を耳にしました。さらに、最近はCNTKもバックエンドに指定できるようになっているらしく、将来はKerasがDeep Learningフレームワークのハブ的な存在になるのでは、と思いました。そのため、Kerasをある程度使えることはDeep Learningで分析をやっていく上で無駄にはならないだろうという判断をしてます。

Keras

Kerasのページ(Keras Documentation)では、以下のような説明がされています。

Kerasは,Pythonで書かれた,TensorFlowまたはCNTK,Theano上で実行可能な高水準のニューラルネットワークライブラリです. Kerasは,迅速な実験を可能にすることに重点を置いて開発されました. アイデアから結果に到達するまでのリードタイムをできるだけ小さくすることが,良い研究をするための鍵になります.


次のような場合で深層学習ライブラリが必要なら,Kerasを使用してください:

  • 容易に素早くプロトタイプの作成が可能(ユーザーフレンドリー,モジュール性,および拡張性による)
  • CNNとRNNの両方,およびこれらの2つの組み合わせをサポート
  • CPUとGPU上でシームレスな動作

TensorFlow、Theano、CNTKのラッパー的な印象を受けます。裏ではこれらが動くけど、ユーザー側が書かなければならないコードは直感的でわかりやすくなっているようです。

インストー

私の環境は以下です。

  • MacOS Sierra, 10.12.2
  • Python3.6.1, anaconda4.4.0
  • pip 9.0.1

ある程度新しいVersionのpipが導入されていれば、pipで簡単にインストールできます。Kerasをpipで入れるとTheanoも同時にインストールされます。ここでは、TensorFlowをバックエンドで動かすことを見越してTensorflowも入れておきます。

$ pip install tensorflow
$ pip install keras

あとはPythonを起動してkerasのimportが成功すればOKです。とりあえず、現時点ではバックエンドで動くフレームワークのデフォルトがTensorflowのようです。

注意:pipのVersionが古いとTensorflowがインストールできない

以下のようなメッセージが出てきます。

# pip install tensorflow
Downloading/unpacking tensorflow
  Could not find any downloads that satisfy the requirement tensorflow
Cleaning up...
No distributions at all found for tensorflow

この場合は

$ pip install -U pip

をしてから再びpipでTensorflowを入れましょう。

littlebird.hatenablog.jp

それでもだめなら、、、環境構築をやり直し…ですかね。。

Next Step

実際に例を用いて実践します。まずはMNISTあたりで。

Memo:BoostのVersionを確認

BoostのVersionを確認したいときに実行するコード

会社のサーバでとあるソフトウェアをPythonとbindingさせようとしたときに、BoostのVersionが知りたくなったので調べてみました。
以下のようなコードを作成して実行するとVersionがわかるようです。

#include <iostream>
#include <boost/version.hpp>

int main()
{
    int major = BOOST_VERSION / 100000;
    int minor = BOOST_VERSION / 100 % 1000;
    int patch = BOOST_VERSION % 100;
    std::cout << "boost version " << major << "." << minor << "." << patch
        << " or " << BOOST_LIB_VERSION << std::endl;
    return 0;
}


ただググっただけですが、ソース元はこちら。
boost/version.hpp - 1.64.0
e-kwsm.hatenablog.com