機械学習ライブラリ進捗2 - 調べ物

このバージョンの時点(前回から更新なし)

バックプロパゲーション(逆誤差伝播法)を実装しようといろいろ調べてた。

- 勾配法というものがあるらしい。今回は実装しない。

- 学習において、CNN層(畳み込み層?)と全結合層は別物として考える必要があるのかと思っていたのだけど、どうやら共通のインターフェースで扱えそうなことがわかった。

- 共通インターフェースで表せそうだということがわかったので実装しようとしたが、いまのつくりではかえって難しいので方向転換をすることにした。
というのは・・・

いまのつくりは、データの基本形をEigen::MatrixXfとして、畳み込み層で複数枚のフィルタがある場合に層を分離させるためにそのstd::vectorを使っていた。

// 抜粋(改変あり)
using Matrix = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
using MatrixArray = std::vector<Matrix, Eigen::aligned_allocator<Matrix>>;

class Layer
{
public:
	virtual MatrixArray proc(const MatrixArray &ma) {
		int num = ma.size();
		MatrixArray ret;
		for(int i = 0; i < num; ++i) {
			MatrixArray &&result = proc(ma[i], i);
			ret.insert(std::end(ret), std::begin(result), std::end(result));
		}
		return ret;
	}
	virtual MatrixArray proc(const Matrix &m, int index)=0;
};
class Convolution : public Layer
{
protected:
	MatrixArray proc(const Matrix &m, int index);
private:
	MatrixArray filter_;
};

ここでprocがMatrixを受け取ってMatrixArrayを返す仕様にしたのは、畳み込み層でフィルタの数だけ分岐する機能を実現する意図があったのだけど、
- その後にもう一度フィルタを通す場合に何番目のフィルタを通すのかを選択するためだけにindexを渡す必要があったり
- 分岐しないLayerであってもMatrixArrayを受け取ってMatrixArrayを返す過剰に複雑な仕様になってしまっていたり
動きはするものの、作りながら「なんだかなあ・・・」と思う設計だった。バックプロパゲーションの実装を考えるにあたってもどう追加したものか悩ましいものになってしまった。

ということで、Matrix(二次元配列)でもMatrixArray(三次元配列)でも同じ型で扱えるように修正をするつもりでいる。

(おまけ)ハイパーパラメータは学習させるものではなく、人間が選ぶものだということを知った。秘伝のタレ的なことですかね。勘所を習得するには数をこなすしかないみたいな。。

疑問

- CNN層という呼び方は適切?
  - その場合畳み込み層のみのこと?
  - 畳み込み、プーリング、活性化等々ひっくるめた呼称?
- ハイパーパラメータはみんなどうやって考えてるの?
- 二・三次元配列を扱えるライブラリとしてboost::multi_arrayを考えているけど他におすすめはある?(C++です)
- 行列計算は必要なのだけどboost::multi_arrayとboost::ublas::matrixを同時に扱う良い方法はある?いちいち変換する必要がある?

この記事が参加している募集

サポートしていただけたら、書く勢いになります!