やりたかったこと3つ

いぜんから、じかんを見つけてやりたいことが3つあり、じっさいに、やっている。

それは、

プログラミング

統計

会計

だ。

もう、んん十年も文章を書いてきている。

さいしょは原稿用紙と鉛筆で書いていたっけ。

それが、ワープロになり、パソコンになっていった。

とうぜん、パソコンを持っている。

なので、プログラミングをはじめるというのは、それほど敷居がたかいと言うわけではない。

はじめれば、はじまるわけね。

それに対して、統計や会計は、距離があった。

ま、こじつければ「統計や会計のソフトをつかえや」ということになるけれど、なかなか、そうはいかない。

で、統計の入り口になってくれたのが「統計学が最強の学問である」という本なんだわ。

それと、プログラミング→機械学習にすすむにつれ、単回帰分析や重回帰分析といったアルゴリズムと、統計のそれが重なってくる。

会計は、さすがに、じかんがとれないなぁ…法人のとき(現在は休眠中)、税理士にまかせっきりでなく、いい機会なので、やっておけば良かったのに。

ラズパイ4とか

ラズベリーパイ4がリリースされた。しかし日本ではまだ購入できない。技適(総務省の認定)による、とされている。

7年前のMacBookAirをつかっている。CPUは1.3GH、メモリは3GBだ。

一方のラズパイ4は、前者が1.5GH、後者はタイプにより1GB、2GB、4GBとなっている。

コンピュータのスペックの指標は、CPUとメモリである、と言ってもよいでしょう。

なので、この7年間で名刺サイズのラズパイ4が、MacBookAirのスペックを抜いてしまった、と言ってしまいたい。

新製品ラズパイ4の前のバージョン、ラズパイ3をつかってみた感想としては、パソコン仕様でつかうには不十分という気がしている。

ラズパイは端子のピン群がついていて、どちらかといえば、センサーなど、ほかの部品とつなぐ機械工作用としてのボードという感想を持っていた。

ちなみに、ホリエモンがプロデュースしているロケットにも、ラズパイが使用されていたんだってよ〜。

ハナシは、ややそれてしまったけれど、ラズパイ4のスペックなら、パソコンとして十分だろうし、いまやクラウド側のスペックをつかうのが主流なので、重い処理、たとえば機械学習にも対応できるよね。今秋からアメリカでスタートするグーグルのクラウド・ゲーム、スタディアだって、できるもんな。

要は、従来のパソコン、
マックやウインドウズ機の価値は薄くなっていく、ということね。

softmax関数

この文字づらに触れた当初、softmap関数と見まちがえいて。

「ははぁ、ソフマップは、この関数からつけた社名なんだな」って、おもったりもした。

こういう、カンちがいは、とても多いんですねぇ、オレ。

ソフマップではなく、ソフマックスの見まちがいでした。

ところで、softmax関数に値を入れると、

その値は、

0 < 出力 <1となる。

そして、

出力の値が複数のばあい、その合計、
出力1+出力2+出力3…=1となる。

で、「これを持って、確率が表現されている」ということは、どうにもシックリいかないんだわ。

確率って、ほら、サイコロを投げて云々の頭があるからさ。

それとも、全事象に対する個別の事象の数ではなく、「0から1の間の値である」「それぞれの事象の合計が1である」を満たすことが、確率の定義なのか。どうなんだろ?

 

MNIST

さいしょにやるプログラミング例は、
たぶん、 print(‘Hello World’)だったりする。

で、機械学習の’Hello World’的なものは、
MNISTという説もある。

MNISTには、機械学習を行うためのプログラミングと、
基本的なデータ・セットがそろっている。

けれど、チュートリアルをやるものの、イマイチどういうふうになっているのか、視覚的に、わからなない。

ここでは、そういうことを、たしかめながら、まとめてみようとおもう。

 

(1)「ゼロから作る Deep Learing」のGit Hub上にあるファイルを使ってみる。

 

まずは、Git Hubからダウンロードしたファイルを、ユーザーのディレクトリに置く。あとは、以下、Anaconda Juputernotebookからの作業となる。

import os

os.chdir('/Users/tsurumakifumiaki/deep-learning-from-scratch-master/ch03')
# カレントディレクトリをch03に変更

import sys

sys.path.append(os.pardir) 
# 親ディレクトリにあるファイル(deep-learning-from-scratch-master)をインポートする

from dataset.mnist import load_mnist 
# dataset.mnistからload_mnist関数をインポートする

(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
# load_mnist関数によりデータセットが読み込まれる(引数は読み込みの際の設定)。
# データは(x_train, t_train), (x_test, t_test)に、それぞれ返される。

print(x_train.shape)
(60000,784)
# 訓練データの数字の画像データ、784個の値のリストが60000個ある

print(t_train.shape)
(60000,)
# その画像の数字、、スカラーが60000個ある

print(x_test.shape) 
(10000,784)
# テストデータの数字の画像データ、784個の値のリストが10000個ある

print(t_test.shape)
(10000,)
# その画像の数字、、スカラーが60000個ある

 

では、じっさいの格納されている画像データをみてみよー。

x_train_number =x_train[5323]

x_train_number

5323番目の文字。784個の値が集合している。
0(まっ白)から、784(まっ黒)、そのあいだの灰色の階調を表す数字が並んでいる。



といっても、コンピュータが認識できても、
ひとの視覚では確認できない。確認できるようにしてみよー。

import matplotlib.pyplot as plt

plt.imshow(train_number_image, cmap = plt.cm.binary,
           interpolation='nearest')

画像は、以下のとおり、3であった。

ちなみに、教師データのラベルも3となっている。

t_train_number =t_train[5323]

t_train_number 

3

# ちゃんと3nの「タグ」が貼られている。


(2)推論処理を行う

 

GitHub上の「ゼロから作るDeepLearning」のフォルダーの中に、訓練用のバイアスと重みのデータが入ったファイルが用意されている。

場所:
deep-learning-from-scratch-master/ch03/sample_weight.pkl

まずは、そのファイルを変数 networkに代入する。

import pickle
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)

スケール感を、たしかめてみよう。

まずは重みの数

len(network['W1'])
784

len(network['W2'])
50

len(network['W3'])
100

 

つぎにバイアスの数

len(network['b1'])
50

len(network['b2']
100

len(network['b3'])
10

 

オッケー、では実装してゆこう。

def get_data():
    (x_train, t_train),(x_test,t_test)=\
    load_mnist (normalize=True,flatten=True,one_hot_label=False)
    return x_test,t_tes

def init_network():
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network

import numpy as np

# シグモイド関数の実装
def sigmoid(x):  
    return 1/(1+np.exp(-x))

# ソフトマックス関数の実装
def softmax(a): 
    exp_a = np.exp(a)
    sum_exp_a = np.sum(exp_a)
    y=exp_a / sum_exp_a
    return y

# 各層で、変数network内にある重みとバイアスを加えていく。
# それぞれの値はシグモイド関数、最後はソフマップ関数を通す。

def predict(network,x):
    w1,w2,w3=network['W1'],network['W2'],network['W3']
    b1,b2,b3=network['b1'],network['b2'],network['b3']
    a1=np.dot(x,w1)+b1
    z1=sigmoid(a1)
    a2=np.dot(z1,w2)+b2
    z2=sigmoid(a2)
    a3=np.dot(z2,w3)+b3
    y=softmax(a3)
    return y


# MNISTデータを取得しxとtに返す
x,t = get_data()

# 重みとバイアスのデータを変数networkに代入する
network = init_network()

# for文により、xに格納された画像データを1枚ずつ取り出し、predict関数により、
# ファイルに用意されている重みとバイアスが試される。
accuracy_cnt ==0
for i in range(len(x)):
    y=predict(network, x[i])
    p=np.argmax(y)
    
    if p==t[i]:
        accuracy_cnt += 1

print(str(float(accuracy_cnt)/len(x)))

0.9533

まとめ▼

さいごのコードは、784枚の画像データに重みとバイアスを付けた最大の値(いちばん高い確率の値)が出力されている、たぶん。このへんが、うまく理解できていなかったりする〜

AIとチベット仏教

AIは、ひとを超えるのか。そういう議論がある。

個人的には、脳に還元される(脳をモデルにする)ことは、AIで実装されるとおもっている。

その境界線にあるのは意識だろう。意識が脳によるものなら、AIも意識的になるかもしれない。

チベット仏教は、こころを分析する哲学ともいえるでしょう。

こころは脳にはない。むしろ、こころの成長が脳を変容させるという。

ちなみに意識や自我には、はじまりもなければ、おわりもないという立場だ。

静かなブームとなっているチベット仏教は、過熱するAIに対する無意識的な批判なのかもな。

論理ゲートをPythonで

ANDゲート、NANDゲート、ORゲートをpythonのクラスで書いてみた〜(XORゲートは、うまく行かず。出力エラーになってしまう)

import numpy as np

class Logic_gate:
    def __init__(self,x1,x2):
        self.x1=x1
        self.x2=x2
        
    def AND(self):
        x=np.array([self.x1,self.x2])
        w=np.array([0.5,0.5])
        b=-0.5
        y=np.sum(x*w)+b
        if y<=0:
            return 0
        else:
            return 1
    
    def NAND(self):
        x=np.array([self.x1,self.x2])
        w=np.array([-0.6,-0.6])
        b=0.8
        y=np.sum(x*w)+b
        if y<=0:
            return 0
        else:
            return 1
    
    def OR(self):
        x=np.array([self.x1,self.x2])
        w=np.array([0.5,0.5])
        b=-0.3
        y=np.sum(x*w)+b
        if y<=0:
            return 0
        else:
            return 1
    
    def XOR(self):
        s1=NAND(self.x1,self.x2)
        s2= OR(self.x1,self.x2)
        y=AND(s1,s2)
        return y
#AND回路の出力

resAND= Logic_gate(0,0)
resAND.AND()
0

resAND= Logic_gate(1,0)
resAND.AND()
0

resAND= Logic_gate(0,1)
resAND.AND()
0

resAND= Logic_gate(1,1)
resAND.AND()
1
#NAND回路の出力

resNAND= Logic_gate(0,0)
resNAND.NAND()
1

resNAND= Logic_gate(1,0)
resNAND.NAND()
1

resNAND= Logic_gate(0,1)
resNAND.NAND()
1

resNAND= Logic_gate(1,1)
resNAND.NAND()
0
#OR回路の出力

resOR=Logic_gate(0,0)
resOR.OR()
0

resOR=Logic_gate(1,0)
resOR.OR()
1

resOR=Logic_gate(0,1)
resOR.OR()
1

resOR=Logic_gate(1,1)
resOR.OR()
1

参考:「ゼロから作るDeepLearning」(斎藤康毅/オライリー・ジャパン)

selfをあえて書かない場合

classの中に引数selfを、あえて書かないという試み。

class Calc():
    def minus(a,b):
        c=a-b
        print(c)
        return

Calc.minus(2,3) *クラスのメソッドに直接アクセスする。

-1              *実行された

res= Calc()
res.minus(2,3)  * インスタンスを作り、メソッドにアクセス。

↓以下のエラーメッセージ
TypeError              Traceback (most recent call last)
<ipython-input-41-ffe44836ebd0> in <module>
      1 res= Calc()
----> 2 res.minus(2,3)
TypeError: minus() takes 2 positional arguments but 3 were given

これのエラーは、minus関数は引数を2つ取るような仕様なのに、引数が3つ与えられている。

=>minusメソッドは、オブジェクト、a、bという3つの引数を取らなければいけないということです。

パーセプトロン

パーセプトロンを理解するために、ANDゲートの結果を教師データとして、重みとバイアスの調節をやってみる。

まず、ANDゲートの概念図なり〜




図の解説

(0,0)を入力したばあいは、0が出力される。
(1,0)を入力したばあいは、0が出力される。
(0,1)を入力したばあいは、0が出力される。
(1,1)を入力したばあいは、1が出力される。

このような出力結果になるように、pythonにて関数を書いてみる。

スカラーのばあい。
(スカラーという言葉つかいに自信なし。後述のベクトルに合わせて、ためしに、この言葉をつかっている)。

ANDゲートの出力結果になるように、重み(w1,w2)とバイアス(b)には任意の数値を入れてある。

def AND(x1,x2):
w1,w2,b=0.5,0.5,-0.7
y=x1*w1+x2*w2+b
if y<=0:
return 0
else:
return 1

ベクトルをつかったばあい。
def AND(x1,x2):
x=np.array([x1,x2])
w=np.array([0.5,0.5])
b=-0.7
y=np.sum(x*w)+b
if y <=0:
return 0
else:
return 1

ためしてみる。
AND(0,0)
0

AND(1,0)
0

AND(0,1)
0

AND(1,1)
1

OK〜

では、このばあい(任意にとったw1,w2,bの数値、順に0.5、0.5,-0.7のばあい)1と0に分かれるx1,x2の領域は、どのようになっているか。

いままで、ANDゲートを実装することを主眼に置いていたけれど、以下、入力値(0,0)、(1,0),(0,1),(1,1)にこだわらず、あくまでも、どのような数値を入力すれば、1と0になるのか、みてみよう。

もういちど、作成した関数をみてみる〜

def AND(x1,x2):
w1,w2,b=0.5,0.5,-0.7
y=x1*w1+x2*w2+b
if y<=0:
return 0
else:
return 1

y=x1*w+x2*w2+bに、
w1=0.5、w2=0.5,b=-0.7を代入する。

y=0.5×1+0.5×2-0.7

このさい、0が閾値になるので、y=0を代入。

0=0.5×1+0.5×2-0.7
0.7=0.5×1+0.5×2
0.5×2=-0.5×1+0.7

両辺を0.5で割る
x2=x1+0.7/0.5
x2=x1+1.4

たぶん大丈夫。
x2=x1+1.4のグラフを書いてみよ〜。

import matplotlib.pyplot as plt
import numpy as np
x1=np.arange(-1,1.1,0.1)
x2=x1+1.4



色を、つけてみよう。

plt.fill_between(x1,x2)




たぶん…ブルーの領域のx1,x2を入力すれば、出力はゼロだったりしそう…

ためしてみよう。

たとえば、
(x1,x2)=>  ?
(0.25,0.25)=> 0
(0.5,1.5)=>1
(0,1.5)=>1
(0,1,4)=>0

よさそう。
ちなみに、x10のさかいは、1.4..だねぇ。

参考:「ゼロから作るDeep Learning」(斎藤康毅/オライリー・ジャパン)

with open( )

pythonのwith open( )について、まとめておこう。

このさいのopen( )は,ファイルを開くときの埋め込み関数。

閉じるときはclose( )関数を利用する。ただし、close( )関数を記述しないで、閉じてしまう場合が多々ある。

そうならないためにwith文を利用する。

じっさに記述してみようか。

//close( )関数を使った場合
path=’/Users/tsurumakifumiaki/test.ipynb’
f=open(path)
type(f)
f.close()

with open(path) as f:
print(type(f))