読者です 読者をやめる 読者になる 読者になる

Javascript 配列の使い方

要素の追加

  • 先頭に追加 unshift
var array = ['b', 'c'];

array.unshift('a');
console.log(array); // ['a', 'b', 'c']
  • 末尾に追加 push
var array = ['a', 'b'];

array.push('c');
console.log(array); // ['a', 'b', 'c']
  • 指定した位置に一つ以上追加 splice
var array = ['a', 'b', 'c'];

array.splice(1, 0, 'A'); // 二番目に挿入
console.log(array); // ['a', 'A', 'b', 'c']

配列の結合

  • 非破壊的な結合 concat
var array1 = ['a', 'b'];
var array2 = ['c', 'd'];

var array = array1.concat(array2);

console.log(array); // ['a', 'b', 'c', 'd']
  • 破壊的な結合 push
var array1 = ['a', 'b'];
var array2 = ['c', 'd'];

Array.prototype.push.apply(array1, array2);

console.log(array1); // ['a', 'b', 'c', 'd']

要素の取得

  • 先頭を取得
var array = ['a', 'b', 'c'];

var value = array[0];

console.log(value); // 'a'
  • 末尾を取得
var array = ['a', 'b', 'c'];

var value = array[array.length - 1];

console.log(value); // 'c'
  • 配列の数を取得
var array = ['a', 'b', 'c'];

var l = array.length;

console.log(l); // 3
  • 値から最初のkeyを取得 indexOf
var array = ['a', 'b', 'c'];

var index = array.indexOf('b');

console.log(index); // 1
  • 値から最後のkeyを取得 lastIndexOf
var array = ['a', 'b', 'c', 'b'];

var index = array.lastIndexOf('b');

console.log(index); // 3
  • 指定した位置から一つ以上の値(配列)の取得
var array = ['a', 'b', 'c', 'd'];

var s1 = array.slice(1, 2);
var s2 = array.slice(1, 3);

console.log(s1); // ['b']
console.log(s2); // ['b', 'c']

要素の削除

  • 先頭を削除 shift
var array = ['a', 'b', 'c'];

array.shift();
console.log(array); // ['b', 'c']
  • 末尾を削除 pop
var array = ['a', 'b', 'c'];

array.pop();
console.log(array); // ['a', 'b']
  • 指定した位置から一つ以上の値を削除 splice
var array = ['a', 'b', 'c'];

array.splice(1, 1); // 二番目から一つ削除
console.log(array); // ['a', 'c']

var array = ['a', 'b', 'c'];

array.splice(1, 2); // 二番目から二つ削除
console.log(array); // ['a']
  • 配列の全要素の削除 length, []
var array = ['a', 'b', 'c'];

array.length = 0;
console.log(array); // []

var array = ['a', 'b', 'c'];

array = [];
console.log(array); // []

JavaScriptの関数

JavaScriptの関数にはfunction文とfunction式の二種類あります。

function文
別名、「関数宣言」です。
このように、function文はc++などでもお馴染みの関数宣言になります。
ただし、JavaScriptではコンパイル時に関数ができるので、関数宣言を呼び出した部分より下で宣言しても大丈夫です。

function hoge() {
  console.log('call hoge');
}

hoge();
fuga();

function fuga() {
  console.log('call fuga');
}

function式
別名、「関数式」です。
このようにfunction式はfunction文と違って式なので、実行されるときに関数が定義されるということです。

var hoge = function () { // 無名関数、匿名関数
  console.log('call hoge');
};

hoge();
try {
  fuga(); // この時点ではfugaはundefinedなので例外を吐く
} catch(e) { console.log('e'); }

var fuga = function Fuga() { // 関数に名前をつけることができる。再帰関数を書くときなどに利用可能
  console.log('call fuga');
};

(function () { // 即時関数
  // スコープを作るためのfunction式
})();

何が起きているのかを一つずつ説明。
JavaScriptの場合は、関数を変数的に見ることが可能です。
一つ目のfunction文は、無名関数を変数hogeに代入しており、その結果、hogeは関数になります。
ただし、代入文の実行時に関数が定義されるため、fuga()の呼び出しで例外が発生します。
またよく見ると、fugaのfunction式には無名関数ではなく、Fugaという名前が付いた関数であることに気づきます。
これはぱっと見意味はわからないかもしれませんが、関数「Fuga」の実態はただの関数オブジェクトになるので関数オブジェクト部分だけ関数「hoge」に代入しているような形です。
この場合、関数が「fuga」と「Fuga」二つ存在しているが、関数「Fuga」はローカルの関数となり、外で呼び出すことはできません。
これではメリットがないように思われますが、関数の中で自分自身を呼ぶ再帰関数を書くために使うことができます。
そして最後、何か()で括られているやつ。
こいつは即時関数と呼ばれるもの。
こいつは一度しか使用しない関数の時に用います。
つまり、スコープがそこだけになり、スコープの汚染を防ぐことができます。
つまり、これより前で宣言したグローバルスコープの変数の値を変えたりされないということです。

HTMLのタグ集

タグとは<>で囲まれたもののことをいう。

!DOCTYPE html:ドキュメントタイプを宣言する
は、文書がHTML5で作成されたものであることを宣言するために、文書の先頭(タグより上)に記述するDOCTYPE宣言。
HTMLは、バージョンによって使用できるタグや属性が異なるので、DOCTYPE宣言でその文書がHTMLのどのバージョンで作成されているかを宣言しなければならない。

html:HTML文書であることを示す
htmlの直下にはheadとbodyがそれぞれ一つずつ必要。

head:文書のメタデータを集めたもの
メタデータとは、文書に関する情報のことで、例えば、title・base・link・style・metaなどが挙げられる。

body:文書本体

ここまでのサンプルコード

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>HTML5サンプル</title>
</head>
<body>
  文書本体
</body>
</html>

title:文書のタイトル
一つの文書に一つだけheadの中に配置する。

meta:文書に関するメタデータ
属性
文字エンコーディング
charser属性は文字エンコーディングを指定する際に使用する。

<meta charset="utf-8">>

キーワード・説明

<meta name="keywords" content="HTML,CSS,JavaScript">
<meta name="description" content="HTMLのタグ集">

文書の作者

<meta name="author" content="takahiro itazuri">

コンテンツ言語

<meta http-equip="content-language" content="ja">

link:リンクする外部ソースの指定
属性
href
  リンクする外部リソースのURL
rel
  現在のファイルとリンク先の外部ファイルとの関係性を表すキーワード

<head>
  <title>タイトル</title>
  <link rel="stylesheet" href="stylesheet.css">
</head>

ImageNet Classification with Deep Convolutional Neural Networks

今や当然のように身近にあるDeep Learning、、、。
そろそろ勉強しなきゃですよね。

今日はこちらのスライドに沿ってお話していこうと思います。

ILSVRC
Deep Learningについて紹介するスライドを見ると必ずと言っていいほど目にする「ILSVRC」という文字。
これはImageNet Large Scale Visual Recognition Challengeの略で、1000個のカテゴリーの120万枚の画像から学習して、クラス分類をする課題のことです。

なぜDeep Learning?
Deep Learning(またの名をDeep Neural Network)が流行る前にも、パーセプトロン(Neural Network)を用いた手法は多く取られていました。
パーセプトロン(Neural Network)とは、人間の脳を模倣してもので、下の図のような構造をしています。

f:id:takahiro-itazuri:20170331003951p:plain

人間の脳は多くのニューロンから構成されていて、ニューロン樹状突起という部分で他のニューロンから刺激を受け取り、入力された刺激がある一定以上になると、軸索終末という部分から信号を出力するといった仕組みになっています。
人間が多くの物体を認識できるように、機械にも同様の構造を持たせて、学ばせて(学習)あげれば人間と同等に物体を認識できるだろうと考えた人達がいました。

f:id:takahiro-itazuri:20170331004413p:plain

つまり、上の図のようにニューロンをつなぎ合わせたモデルを使って物体認識をさせようということです。
Deep Learning以前では、入力の信号として従来からcomputer visionの分野で用いられていた特徴量を用いて、学習させていました。
しかし、これでは指定した特定の特徴量しか入力されません。
そこで、入力される特徴量さえもこのモデルが自動的に作るような構造(architecture)を開発しました。
これがまさにDeep Neural Network(Deep Learninig)なのです。

f:id:takahiro-itazuri:20170331004850p:plain

特徴量を自動的に作る部分がどのように行われているか説明します。
従来からcomputer visionではガウシアンフィルタ(画像をぼかすフィルタ)やキャニーフィルタ(エッジを抽出するフィルタ)といったようにフィルタを用いて特徴量を抽出していました。
画像の特定の領域と予め用意しておいたフィルタを畳み込む操作をフィルタリングと呼ばれています。

f:id:takahiro-itazuri:20170331005357p:plain

このフィルタの値を上手く作ることで、これまで画像をぼかしたり、エッジを抽出したりしてきました。
これらが特徴量として用いられていました。
したがって、このフィルタを上手く作ることができれば、うまく分類ができそうですね。
そこで画像認識の分野ではConvolutional Neural Networkといって、このフィルタの値を学習する構造(architecture)となっています。

f:id:takahiro-itazuri:20170331005657p:plain

このように従来は人間お手製の特徴量を使っていた部分までもを学習するものがDeep Learningということになります。

Deep Learningの問題点
ここまで見てきたDeep Learningはまさしく機械が人間と同じ構造を持ち、まるでSF映画の世界です。
しかし、この万能に見えるDeep Learningにもいくつか欠点があります。

まず一つ目は6000万個のパラメータを学習しなければならないことです。
この読者にはまだ「学習ってなんや?」とわからない方がいらっしゃるかもしれませんが、兎にも角にもなんか膨大な量を学習しなきゃいけないんだということはわかると思います。
つまり膨大な計算量が必要なのです。
人間の脳がどれだけ複雑な構造をしているかは想像にたやすいでしょう。
それを機械の中に構築し、学習させるのは大変そうだということくらいはわかります。
しかし、最近では並列計算を得意とするGPUや効率よく学習するための工夫が多く登場しており、これが原因ともなってDeep Learningが流行っています。

次に二つ目の欠点は、学習するデータが膨大に必要になることです。
人間が10歳になるころにはどれだけ多くの情報と触れ合っているかを想像すれば、膨大な量のデータが必要になるのは当たり前のように感じるでしょう。
しかし、こちらもdata augumentationといって、少ないデータを上手く加工してデータ数をむりやり増やす(data augumentation)という技術が出ています。

Deep Learningの今後
このようなDeep Learningにおける欠点とされていた問題点がどんどんと解決されており、近年急成長を見せています。
ただまだ理論的な裏付けの部分が研究されていたり、当面の問題は多く残っています。
今後もDeep Learningは何かと世間を騒がせることになるでしょう。
今回はここで終わりますが、今後もよりDeep Learningの理解を深めるための記事を投稿していこうと思います。

最後まで読んでいただきありがとうございました。
よろしかったら読者登録お願いします。
それでは。

ファイルの選択ダイアログ

アプリケーションでファイルを選択するダイアログが出てきますが、これを自分のコードでも書いてファイルを指定したいですよね?(僕だけか??)

このダイアログを出すためにはGetOpenFileName()関数を使います。

BOOL GetOpenFileName(LPOPENFILENAME lpofn);

lpofnには、初期化情報を格納したOPENFILENAME構造体へのポインタを指定します。
ユーザがファイルを選択すれば0以外、そうでなければ0が返ります。

OPENFILENAME構造体は次のような定義になっています。

typedef struct tagOFN {
    DWORD         IStructSize;
    HWND          hwndOwner;
    HINSTANCE     hInstance;
    LPCTSTR       lpstrFilter;
    LPTSTR        lpstrCustumFilter;
    DWORD         nMaxCustFilter;
    DWORD         nFilterIndex;
    LPTSTR        lpstrFile;
    DWORD         nMaxFile;
    LPTSTR        lpstrFileTitle;
    DWORD         nMaxFileTitle;
    LPCTSTR       lpstrInitialDir;
    LPCTSTR       lpstrTitle;
    DWORD         Flags;
    WORD          nFileOffset;
    WORD          nFileExtension;
    LPCTSTR       lpstrDefExt;
    DWORD         lCustData;
    LPOFNHOOKPROC lpfnHook;
    LPCTSTR       lpTemplateName;
} OPENFILENAME;
  • lStructSizeにはこの構造体のサイズを指定します
  • hnwdOwnerは、ダイアログボックスの親ウィンドウのハンドルを指定します
  • hInstanceは、ダイアログボックステンプレートを用いる場合にテンプレートを含むモジュールのインスタンスハンドルを指定します
  • lpstrFilterには、選択対象のファイルをフィルタリングするための文字列を指定します。この文字列は、表示文字列\0フィルタ文字列という形で指定します。表示文字列はダイアログのリストボックスに表示される文字列でフィルタ文字列は、フィルタパターンを指定します。例えば、"Text(*.txt)\0*.txt"とすれば、拡張子がtxtのファイルのみが表示されます。
  • lpstrCustomFilterは、ユーザ定義のフィルタ文字列バッファへのポインタを指定します。これはlpstrFilter同様に表示文字列とフィルタ文字列の組み合わせです。システムは選択されたフィルタパターンをこのバッファに保存します。表示文字列は変わりませんが、フィルタは最後に保存されたものになっている。
  • nMaxCustFilterには、lpstrCustomFilterのバッファサイズを指定します。この長さは最低でも40文字分以上のサイズを指定しなければなりません。lpstrCustomFilterがNULLの場合は無視されます。
  • nFilterIndexには、ダイアログの初期設定のフィルタインデックスを指定します。0を指定すれば、ユーザ定義のカスタムフィルタを表します。
  • lpstrFileは、ファイル名が格納される256文字以上のバッファへのポインタを指定します。このバッファに、選択されたファイルの降るパスが格納されます。
  • nMaxFileにはlpstrFileが指すバッファサイズを指定します。
  • lpstrFileTitleには、ファイルタイトルを格納するバッファへのポインタを指定します。ファイルタイトルとは、ドライブ名とディレクトリ名をの除いた、ファイル自体の名前です。必要ないときはNULLを選択してください。
  • nMaxFileTitleには、lpstrFileTitleが指すバッファサイズを指定します。
  • lpstrInitialDirは、初期のファイルでぃれえくとりを表す文字列のポインタを指定します。このメンバがNULLの場合、選択ダイアログはカレントディレクトリを表示します。
  • lpstrTitleには、ダイアログのタイトルバーに表示する文字列を指定します。NULLを指定すれば、デフォルトの文字がタイトルバーに表示されます。
  • Flagsはダイアログ作成のフラグを指定します。
  • nFileOffsetはlpstrFileが指す文字列内におけるパスの先頭からファイル名までの0から数えたオフセットを表します。
  • nFileExtensionは、lpstrFileが指す文字列内におけるパスの先頭からファイル名拡張しまでの0から数えたオフセットを表します。
  • lpstrDetExtには、デフォルトの拡張子を表す文字列へのポインタを指します。ユーザが拡張子を入力しなかった場合、この拡張子が用いられます。
  • lCustDataはフック関数に渡す追加データを指定します。
  • lpfnHookには、フック関数へのポインタを指定します。
  • lpTemplateNameは、ダイアログテンプレートを使用する場合に、テンプレート名を指定します。

ハンドルとは

APIに引き続き、僕がよく聞くけどあまりよくわかっていないものの一つとして、今回は「ハンドル」について調べます。

ハンドルとは?
ハンドルとは、ファイル等を識別する番号のこと。
実際は、そのポインタを整数にキャストしたものである。

ウィンドウハンドルの例
HWND型はウィンドウハンドル型というデータ型です。
ウィンドウハンドル型の変数は、"ウィンドウハンドル"のためのものです。
つまり、ウィンドウハンドル値を得たら、これに代入します。

HWND型で宣言された変数は、"ウィンドウ"を識別するための値である。"ウィンドウハンドル"を格納するための"変数"です。
そして、その変数に正しいウィンドウハンドルが入っている上で、その変数をもってして"ウィンドウハンドル"というのが通常です。

つまりウィンドウを操作するときは、ウィンドウハンドルでウィンドウを指定して、そのウィンドウを操作するということになります。

dllの作り方

先程dllとlibについての話を簡単に書きました。 そこでdllについてもう少し理解を深めるために、作り方を通して勉強していこうと思います。

何を作るのがゴールになるのか
最終的なゴールは次の3つを作成することになります。
| 拡張子 | 説明 | | :—: | :—: | | dll | 実行時に呼び出されるDLLライブラリ | | lib | コンパイル時に使用するライブラリ | | h | DLLのヘッダファイル |

普通の関数は、プログラム本体の一部として組み込まれているが、DLLは関数だけがコンパイルされて、dllという拡張しの別ファイルになっている。
プログラムの実行時にロードされ、あとは普通の関数と同じように実行される。
DLLだけだと、コンパイル次にどのようなインターフェースになっているかわからないので、これ以外に

  • Cのプロトタイプを記述したヘッダファイル
  • DLLのコンパイル時に、コンパイラが出力するDLLの入出力情報が記述されたlibファイルが使われる。

呼び出し側のプログラムは、DLLのヘッダファイルをインクルードして、普通の関数と同様に呼び出す。

DLLのリンクは、DLLのインターフェースを記述してlibファイルを指定して、コンパイラにリンクを任すようにする。

コンパイラは実行時にDLLをロードして実行するようにコンパイルする。

作り方

  1. Visual Studio で[ファイル]->[新規作成]->[プロジェクト]で新しいプロジェクトを作成

f:id:takahiro-itazuri:20170328213252p:plain

  1. Visual C++ で[空のプロジェクト]を選択し、名前には自分の作りたいDLLファイルの名前を入れる。

f:id:takahiro-itazuri:20170328213459p:plain

  1. hppファイルとcppファイルを作成

f:id:takahiro-itazuri:20170328214053p:plain

  1. hppファイルに次のように書く

f:id:takahiro-itazuri:20170328215002p:plain

  1. ソリューションエクスプローラ内のプロジェクトを右クリックし、[プロパティ]を選択。

f:id:takahiro-itazuri:20170328213759p:plain

  1. [全般]->[構成の種類]->[ダイナミックライブラリ(.dll)]を選択。ただし、構成とプラットフォームは自分の環境に合わせる

f:id:takahiro-itazuri:20170328213931p:plain

  1. [C/C++]->[プリプロセッサ]->[プリプロセッサの定義]に先程hppで書いたifdef文の部分を書き入れる

f:id:takahiro-itazuri:20170328215151p:plain

  1. 変更を[適用]する。すると、hppで書いたifdef文がdefineされたことになり、色が変わる。

f:id:takahiro-itazuri:20170328215417p:plain

  1. あとはdllにしたい関数を実装していく。

プロトタイプはhppに実装し、関数の中身はcppに実装する。 ただし、プロトタイプの頭にdefineした部分を書く

f:id:takahiro-itazuri:20170328220617p:plain