MNISTデータについて

備忘録としてMNISTデータの読み込み方法を忘れないように記載しておきます。

そもそもMNISTデータセットとは機械学習のための、0~9までの手書き文字の訓練画像60,000枚、テスト画像10,000万枚で構成されています。詳しくは、英語しか見つからなかったけどWikipediaをご参照ください。→(MNIST database - Wikipedia)

データの仕様はこのサイトが詳しく書かれていました。→(MNIST データの仕様を理解しよう

とりあえずデータをダウンロードすると4つのファイルが落ちてきます。

train-images-idx3-ubyte: 学習用の画像セット
train-labels-idx1-ubyte: 学習用のラベルセット
t10k-images-idx3-ubyte: 検証用の画像セット
t10k-labels-idx1-ubyte: 検証用のラベルセット

とりあえずデータを読み込んで、データの形を確認してみます。
なお、本ブログではゼロから作るDeep Learningのコードを参照しているので、datasetというフォルダに上記の4ファイルおよびmnist.pyが入っていると想定しています。

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
from dataset.mnist import load_mnist # mnist.pyのload_mnist関数を呼び出す。

(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False) # mnistデータ読み込むためのコード

print(x_train.shape) # (60000, 784)
print(t_train.shape) # (60000,)
print(x_test.shape) # (10000, 784)
print(t_test.shape) # (10000,)

(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)で読み込み、データの形を確認すると、訓練データは60,000個の784次元(28 x 28のグレー画像)、テストデータは10,000個の784次元(28 x 28のグレー画像)であることがわかります。

さらに、load_mnist関数の中身は以下の感じです。
P73〜74に何をしているかは書かれています。

def load_mnist(normalize=True, flatten=True, one_hot_label=False):
    """MNISTデータセットの読み込み
    
    Parameters
    ----------
    normalize : 画像のピクセル値を0.0~1.0に正規化する
    one_hot_label : 
        one_hot_labelがTrueの場合、ラベルはone-hot配列として返す
        one-hot配列とは、たとえば[0,0,1,0,0,0,0,0,0,0]のような配列
    flatten : 画像を一次元配列に平にするかどうか 
    
    Returns
    -------
    (訓練画像, 訓練ラベル), (テスト画像, テストラベル)
    """
    dataset = {}
    for key in key_file.keys():
        if not os.path.exists(get_save_file_path(key)):
            init_mnist(key)

Saveしたfileがある場合は init_mnist()をスキップする

        with open(get_save_file_path(key), 'rb') as f:
            dataset[key] = np.array(pickle.load(f))

セーブしたデータを読み込んで、1次元配列で読み込み

    if normalize:
        for key in ('train_img', 'test_img'):
            dataset[key] = dataset[key].astype(np.float32)
            dataset[key] /= 255.0

読み込んだデータを正規化する。(ピクセル数255で割る)

 if one_hot_label:
        dataset['train_label'] = _change_ont_hot_label(dataset['train_label'])
        dataset['test_label'] = _change_ont_hot_label(dataset['test_label'])    

On hot labelに変換する

    if not flatten:
         for key in ('train_img', 'test_img'):
            dataset[key] = dataset[key].reshape(-1, 1, 28, 28)

もし1次元配列で読み込まない場合は1 x 28 x 28の3次元配列で読み込む

    return (dataset['train_img'], dataset['train_label']), (dataset['test_img'], dataset['test_label']) 
if __name__ == '__main__':

Deeplearning ch02 or_gate.py

ORゲートを設定します。基本的に、ANDゲートと閾値の大きさ以外は全て同じです。
閾値を0.7から重み\omega_1,\omega_2の0.5より小さい0.2に変更することで、入力信号x_1,x_2のどちらかに1が入力された場合にも1を出力するようにしています。

import numpy as np

def OR(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.2
    tmp = np.sum(w*x) + b
    if tmp <= 0:
        return 0
    else:
        return 1
if __name__ == '__main__':
    for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
        y = OR(xs[0], xs[1])
        print(str(xs) + " ->" + str(y)

Deeplearning ch02 and_gate.py

Chapter 02

第1章はnumpyのざっとした説明とmatplotlibの使い方の説明でしたが、第2章よりDeep Learning (深層学習に向けて初歩的なアルゴリズムパーセプトロンとAND、NAND、OR、XORゲートのプログラム内容の紹介をします。(第3章にニューロラルネットワークの説明があります。)

パーセプトロンとはパーセプトロン(perceptron)は、心理学者・計算機科学者のフランク・ローゼンブラットが1957年に考案し、1958年に論文を発表した、人工ニューロンニューラルネットワークの一種。(Wikipediaより)複数の入力信号を処理して、一つ出力を行うアルゴリズムです。ここで言う「処理」とは信号を流す(1)か流さない(0)かを決める処理となります。

パーセブトロンのアルゴリズムを式で表すと以下のようになります。
{y=\begin{eqnarray}\begin{cases}0\ (\omega_1x_1 + \omega_2x_2 \leqq\theta) \\1\ (\omega_1x_1 + \omega_2x_2 >\theta)\end{cases}\end{eqnarray}}
yは出力信号、x_1,x_2は入力信号、\omega_1,\omega_2は重み、\theta閾値(しきいち)を表します。入力信号に重みを掛けたものの総和が閾値を超えると出力信号1が出力されます。

import numpy as np

def AND(x1, x2):
     x = np.array([x1, x2])
     w = np.array([0.5, 0.5])
     b = -0.7
     tmp = np.sum(w*x) + b
    if tmp <= 0:
    return 0
    else:
   return 1

if __name__ == '__main__':
for xs in [(0, 0), (1, 0), (0, 1), (1, 1)]:
y = AND(xs[0], xs[1])
print(str(xs) + " -> " + str(y))

⇒ 重み\omega_1,\omega_2が0.5、\theta閾値が0.7のAND関数を定義します。入力信号x_1,x_2がそれぞれ(1,1)だとすると、{y=\begin{eqnarray}\ (1*0.5 + 1*0.5) - 0.7\ = 0.3>0.0\end{eqnarray}}となり出力信号1が出力されます。入力信号x_1,x_2がそれぞれ(0,0)とすると{y=-0.7\leqq\theta}、(1,0)とすると{y=-0.3\leqq\theta}となり、出力信号は全て0です。

入力信号が0,1である理由は、パーセプトロンの組み合わせにより、複雑な関数であってもパーセプトロンで表現できるという利点を前提としており、パーセプトロンからの出力(0,1)が次のパーセプトロンに入力されると想定しているためです。

Deeplearning ch01 sin_cos_graph.py

SinとCosのグラフをmatplotlibで描画する練習です。simple_graph.pyのグラフになかったラベルと線のスタイルを設定しています。(ラベルと線のスタイル以外の補足説明は省略しています。)

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 6, 0.1) 
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, label="sin")
plt.plot(x, y2, linestyle = "--", label="cos")

⇒ linestyle = " XXX "を挿入することでグラフの線のスタイルの指定ができます。‘その他実線 '-' 、 ダッシュドット '-.'、 ドット':'等があります。

plt.xlabel("x")

⇒ x軸のラベルを"x"とします。

plt.ylabel("y")

⇒ y軸のラベルを"y"とします。

plt.title('sin & cos')

⇒ グラフのタイトルを'sin & cos'とします。

plt.legend()
plt.show()

⇒ 凡例を表示させます。設定したlabel="XXX"が凡例として表示されます。

Deeplearning ch01 sin_graph.py

このプログラムはmatplotlibを使用してSin関数のグラフを表示させます。NumPyとmatplotlibの使い方の練習です。

import numpy as np

⇒ NumPyモジュールをnpという名前でインストールする事を表しています。

NumPy(ナムパイまたはナンパイ)は、プログラミング言語Pythonにおいて数値計算を効率的に行うための拡張モジュールで、効率的な数値計算を行うための型付きの多次元配列(例えばベクトルや行列などを表現できる)のサポートをPythonに加えるとともに、それらを操作するための大規模な高水準の数学関数ライブラリを提供しています。(Wikipediaより)

ベクトル、行列計算が簡単にPythonプログラムで行えますよと個人的には理解しています。Deep Learningにおいて、画像を解析する際に画像データ情報がベクトル、行列で表されているので、計算が簡単にできたら便利です。

import matplotlib.pyplot as plt

⇒ matplotlibのmatplotlib.pyplotモジュールをpltという名前でインストールする事を表しています。import (Module) as (略称)の形式はPythonのモジュールをインストールする一般的な形式で(略称)を宣言することで、以降の文章でモジュール名も簡略化できるのでタイピングが楽になります。

x = np.arange(0, 6, 0.1) # 0から6まで0.1刻みで生成
y = np.sin(x)

⇒x軸方向の範囲を0≦x≦6で0.1刻み、yはxの値に対してのグラフをSin関数とするを指定します。arangeのrangeは範囲という意味です。

plt.plot(x, y)
plt.show()

⇒グラフを描きます。

Deeplearning ch01 img_show.py

とりあえずゼロから作るDeep Learningの本を読んで、理解した内容をプログラム内容と共に書いていきます。

import matplotlib.pyplot as plt

⇒ matplotlibはグラフ描画のためのライブラリで、計算結果をグラフにできます。Jupyter notebookをAnacondaごとインストールするのがベストです。

この最初の言葉はmatplotlibのmatplotlib.pyplotモジュールをpltという名前でインストールする事を表しています。import (Module) as (略称)の形式はPythonのモジュールをインストールする一般的な形式で(略称)を宣言することで、以降の文章でモジュール名も簡略化できるのでタイピングが楽になります。

from matplotlib.image import imread

⇒ matplotlib.imageモジュールを立ち上げてimread --- ファイルから画像を読み込むことを宣言します。

img = imread('../dataset/lena.png') # 画像の読み込み

⇒ どこから画像を読み込むかを記載します。

../ 一つ上の階層のdataset/というフォルダのlena.png画像を読み込みます。

plt.imshow(img)
plt.show()

⇒ 画像imgを描画します。

はじめに

【自己紹介】

30代のサラリーマンです。大学で物理、大学院で地球科学を学び、会社で工業プラントエンジニアを経たのち、現在は経理の関連の仕事をしています。最近興味をもった人工知能を理解するため、PythonDeep Learningを勉強しています。

 

【ブログの内容】

日々のプログラミング関連の勉強についての備忘録を記載していきます。プログラミングは大学時代に少し(しかもFortranを)書いたことがあるくらいなので、ほぼ初心者です。もし、内容に関して不明確な点、誤り等がありましたらコメントいただけたら嬉しいです。

その他、何か書きたいことがあったら書いていきます。

 

  • Pythonを勉強中です。
  • Anaconda3パッケージを使用しています。
  • その他具体的な勉強内容
  1. ゼロから作るDeep Learning --- Pythonで学ぶディープラーニングの理論と実装:Deep Learning(深層学習)について学べる本です。プログラミング言語Python(3.x.x)です。説明がとても丁寧で、ページの関係により省略している説明以外は容易に理解できます。数学的な知識の素養(行列計算、微積分等)が多少必要です。

     

    ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

    ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装