Skip to content

Commit 823634e

Browse files
committed
Change file configurations.
1 parent 87494be commit 823634e

20 files changed

+343
-49
lines changed

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.pythonPath": "/Users/tatsuya/miniconda3/bin/python"
3+
}

_contents/python/logistic-regression-01.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ $$
1818

1919
$$
2020
\begin{aligned}
21-
\mathbf{y} = \text{sigmoid}(\mathbf{Ax} + \mathbf{b}) \\
22-
\mathbf{y} = \text{softmax}(\mathbf{Ax} + \mathbf{b}) \\
21+
\mathbf{y} &= \text{sigmoid}(\mathbf{Ax} + \mathbf{b}) \\
22+
\mathbf{y} &= \text{softmax}(\mathbf{Ax} + \mathbf{b}) \\
2323
\end{aligned}
2424
$$
2525

2626
のようにする。特にsigmoid関数を使うものをロジスティック回帰という(softmaxを使うものも含む場合もある)。なお、sigmoid関数、softmax関数はそれぞれ次のように表される。
2727

2828
$$
2929
\begin{aligned}
30-
\text{sigmoid}(x) = \frac{1}{1 + e^{-x}} \\
31-
\text{softmax}(\mathbf{x})_i = \frac{e^{x_i}}{\sum_{k=1}^d e^{x_k}}
30+
\text{sigmoid}(x) &= \frac{1}{1 + e^{-x}} \\
31+
\text{softmax}(\mathbf{x})_i &= \frac{e^{x_i}}{\sum_{k=1}^d e^{x_k}}
3232
\end{aligned}
3333
$$
3434

@@ -55,7 +55,8 @@ X = X.astype('float32')
5555

5656
```python
5757
from sklearn.linear_model import LogisticRegression
58-
clf = LogisticRegression(random_state=0, multi_class='multinomial', max_iter=20).fit(X, y)
58+
clf = LogisticRegression(random_state=0, multi_class='multinomial', max_iter=20)
59+
clf.fit(X, y)
5960
```
6061

6162
少し時間がかかるが、しばらくすると学習が終わる。なお上記のコード内での `y` は整数型のラベルを格納したNumPyの配列で良い(分かりやすくするために名前を変更した)。

_contents/python/logistic-regression-02.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ dLdb = np.dot(dLdt, dtdb)
132132

133133
### 確率的勾配法
134134

135-
ただ、残念なことにMNISTの場合でいえば60000もある学習データ全てに対しての平均を計算することは、計算効率があまり良くない。今回は数字が10種類しかないので、おそらく60000万個を一度に考えなくても、それなりの数のデータをサンプルして勾配を計算すれば全体の平均で計算した勾配と似たものが得られそうだ。
135+
ただ、残念なことにMNISTの場合でいえば60000もある学習データ全てに対しての平均を計算することは、計算効率があまり良くない。今回は数字が10種類しかないので、おそらく60000個を一度に考えなくても、それなりの数のデータをサンプルして勾配を計算すれば全体の平均で計算した勾配と似たものが得られそうだ。
136136

137137
このような確率的なサンプリングにより選んだデータから勾配を計算する方法を確率的勾配法と呼ぶ。特に最急降下法の勾配をサンプルしたデータから選ぶ方法を**確率的最急降下法** (SGD = stochastic gradient descent) と呼ぶ。今回のMNISTのケースで言えば、だいたい30-50くらいのサンプルを取って勾配を計算すれば、十分にうまく収束する。
138138

_contents/python/read-binary.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,10 @@ pixels = np.asarray(pixels, dtype='uint8')
6666
pixels = pixels.reshape((height, width))
6767
```
6868

69-
試しに表示してみる
69+
次に**Matplotlib**を使って、この画像を表示してみる
7070

7171
```python
72+
import matplotlib.pyplot as plt
7273
plt.imshow(pixels)
7374
plt.show()
7475
```

_programs/python/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.ipynb_checkpoints/*
2-
mnist/*
2+
*/mnist/*
3+
*/kmnist/*
34

45
.DS_Store

_programs/python/environment.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: beginners
2+
channels:
3+
- conda-forge
4+
dependencies:
5+
- python>=3
6+
- numpy
7+
- scipy
8+
- opencv
9+
- requests
10+
- matplotlib
11+
- scikit-learn
12+
- scikit-image
13+
- conda-forge::jupyterlab
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# ロジスティック回帰 -その1-"
8+
]
9+
},
10+
{
11+
"cell_type": "code",
12+
"execution_count": 1,
13+
"metadata": {},
14+
"outputs": [],
15+
"source": [
16+
"import os\n",
17+
"import struct\n",
18+
"import numpy as np\n",
19+
"import matplotlib.pyplot as plt\n",
20+
"from sklearn.linear_model import LogisticRegression"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": 2,
26+
"metadata": {},
27+
"outputs": [],
28+
"source": [
29+
"# MNISTのファイル (あらかじめダウンロードしておく)\n",
30+
"train_image_file = 'mnist/train-images-idx3-ubyte'\n",
31+
"train_label_file = 'mnist/train-labels-idx1-ubyte'\n",
32+
"test_image_file = 'mnist/t10k-images-idx3-ubyte'\n",
33+
"test_label_file = 'mnist/t10k-labels-idx1-ubyte'"
34+
]
35+
},
36+
{
37+
"cell_type": "markdown",
38+
"metadata": {},
39+
"source": [
40+
"## データの読み込み"
41+
]
42+
},
43+
{
44+
"cell_type": "code",
45+
"execution_count": 3,
46+
"metadata": {},
47+
"outputs": [],
48+
"source": [
49+
"def load_images(filename):\n",
50+
" \"\"\" MNISTの画像データを読み込む \"\"\"\n",
51+
"\n",
52+
" fp = open(filename, 'rb')\n",
53+
" \n",
54+
" # マジックナンバー\n",
55+
" magic = struct.unpack('>i', fp.read(4))[0]\n",
56+
" if magic != 2051:\n",
57+
" raise RuntimeError('Invalid MNIST file!')\n",
58+
" \n",
59+
" # 各種サイズ\n",
60+
" n_images, height, width = struct.unpack('>iii', fp.read(4 * 3))\n",
61+
" \n",
62+
" # 画像の読み込み\n",
63+
" total_pixels = n_images * height * width\n",
64+
" images = struct.unpack('>' + 'B' * total_pixels, fp.read(total_pixels))\n",
65+
" \n",
66+
" images = np.asarray(images, dtype='uint8')\n",
67+
" images = images.reshape((n_images, height, width, 1))\n",
68+
" \n",
69+
" # 値の範囲を[0, 1]に変更する\n",
70+
" images = images.astype('float32') / 255.0\n",
71+
" \n",
72+
" fp.close()\n",
73+
" \n",
74+
" return images"
75+
]
76+
},
77+
{
78+
"cell_type": "code",
79+
"execution_count": 4,
80+
"metadata": {},
81+
"outputs": [],
82+
"source": [
83+
"def load_labels(filename):\n",
84+
" \"\"\" MNISTのラベルデータを読み込む \"\"\"\n",
85+
"\n",
86+
" fp = open(filename, 'rb')\n",
87+
" \n",
88+
" # マジックナンバー\n",
89+
" magic = struct.unpack('>i', fp.read(4))[0]\n",
90+
" if magic != 2049:\n",
91+
" raise RuntimeError('Invalid MNIST file!')\n",
92+
" \n",
93+
" # 各種サイズ\n",
94+
" n_labels = struct.unpack('>i', fp.read(4))[0]\n",
95+
" \n",
96+
" # ラベルの読み込み\n",
97+
" labels = struct.unpack('>' + 'B' * n_labels, fp.read(n_labels))\n",
98+
" labels = np.asarray(labels, dtype='int32')\n",
99+
" \n",
100+
" fp.close()\n",
101+
" \n",
102+
" return labels"
103+
]
104+
},
105+
{
106+
"cell_type": "code",
107+
"execution_count": 5,
108+
"metadata": {},
109+
"outputs": [],
110+
"source": [
111+
"def to_onehot(labels):\n",
112+
" \"\"\" one-hot形式への変換 \"\"\"\n",
113+
" return np.identity(10)[labels]"
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"execution_count": 6,
119+
"metadata": {},
120+
"outputs": [],
121+
"source": [
122+
"images = load_images(train_image_file)\n",
123+
"labels = load_labels(train_label_file)\n",
124+
"onehot = to_onehot(labels)"
125+
]
126+
},
127+
{
128+
"cell_type": "markdown",
129+
"metadata": {},
130+
"source": [
131+
"## scikit-learnによるロジスティック回帰"
132+
]
133+
},
134+
{
135+
"cell_type": "code",
136+
"execution_count": 7,
137+
"metadata": {},
138+
"outputs": [
139+
{
140+
"name": "stderr",
141+
"output_type": "stream",
142+
"text": [
143+
"/Users/tatsuya/miniconda3/envs/beginners/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:763: ConvergenceWarning: lbfgs failed to converge (status=1):\n",
144+
"STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n",
145+
"\n",
146+
"Increase the number of iterations (max_iter) or scale the data as shown in:\n",
147+
" https://scikit-learn.org/stable/modules/preprocessing.html\n",
148+
"Please also refer to the documentation for alternative solver options:\n",
149+
" https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n",
150+
" n_iter_i = _check_optimize_result(\n"
151+
]
152+
},
153+
{
154+
"data": {
155+
"text/plain": [
156+
"LogisticRegression(max_iter=20, multi_class='multinomial', random_state=0)"
157+
]
158+
},
159+
"execution_count": 7,
160+
"metadata": {},
161+
"output_type": "execute_result"
162+
}
163+
],
164+
"source": [
165+
"n = len(images)\n",
166+
"X = images.reshape((n, -1))\n",
167+
"y = labels.reshape((n))\n",
168+
"clf = LogisticRegression(random_state=0, multi_class='multinomial', max_iter=20)\n",
169+
"clf.fit(X, y)"
170+
]
171+
},
172+
{
173+
"cell_type": "markdown",
174+
"metadata": {},
175+
"source": [
176+
"## テストデータを用いた精度計算"
177+
]
178+
},
179+
{
180+
"cell_type": "code",
181+
"execution_count": 8,
182+
"metadata": {},
183+
"outputs": [
184+
{
185+
"name": "stdout",
186+
"output_type": "stream",
187+
"text": [
188+
"Accuracy: 0.9130\n"
189+
]
190+
}
191+
],
192+
"source": [
193+
"test_images = load_images(test_image_file)\n",
194+
"test_labels = load_labels(test_label_file)\n",
195+
"pred_labels = clf.predict(test_images.reshape(10000, -1))\n",
196+
"acc = (pred_labels == test_labels).mean()\n",
197+
"print('Accuracy: {:.4f}'.format(acc))"
198+
]
199+
}
200+
],
201+
"metadata": {
202+
"kernelspec": {
203+
"display_name": "Python 3",
204+
"language": "python",
205+
"name": "python3"
206+
},
207+
"language_info": {
208+
"codemirror_mode": {
209+
"name": "ipython",
210+
"version": 3
211+
},
212+
"file_extension": ".py",
213+
"mimetype": "text/x-python",
214+
"name": "python",
215+
"nbconvert_exporter": "python",
216+
"pygments_lexer": "ipython3",
217+
"version": "3.9.1"
218+
}
219+
},
220+
"nbformat": 4,
221+
"nbformat_minor": 4
222+
}

_programs/python/download.py _programs/python/logistic/download.py

+29-12
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
1-
import gzip
21
import os
32
import sys
3+
import gzip
44

55
import requests
66

7-
url = 'http://yann.lecun.com/exdb/mnist/'
8-
x_train_file = 'train-images-idx3-ubyte.gz'
9-
y_train_file = 'train-labels-idx1-ubyte.gz'
10-
x_test_file = 't10k-images-idx3-ubyte.gz'
11-
y_test_file = 't10k-labels-idx1-ubyte.gz'
12-
137
curdir = os.path.abspath(os.path.dirname(__file__))
14-
outdir = os.path.join(curdir, 'mnist')
158

169
CHUNK_SIZE = 32768
1710

1811

19-
def main():
12+
def download(name, url, files):
13+
outdir = os.path.join(curdir, name)
2014
if not os.path.exists(outdir):
2115
os.makedirs(outdir)
2216

23-
files = [x_train_file, y_train_file, x_test_file, y_test_file]
2417
for f in files:
2518
# Download files
2619
session = requests.Session()
@@ -44,11 +37,35 @@ def main():
4437

4538
# Unzip
4639
unzip_file = os.path.splitext(local_file)[0]
47-
with open(unzip_file, 'wb') as fout, gzip.open(local_file,
48-
'rb') as fin:
40+
with open(unzip_file, 'wb') as fout, gzip.open(local_file, 'rb') as fin:
4941
data = fin.read()
5042
fout.write(data)
5143

44+
os.remove(local_file)
45+
46+
47+
def main():
48+
urls = [
49+
('mnist', 'http://yann.lecun.com/exdb/mnist/'),
50+
('kmnist', 'http://codh.rois.ac.jp/kmnist/dataset/kmnist/'),
51+
]
52+
53+
target = 0
54+
while target <= 0:
55+
for i, (name, url) in enumerate(urls):
56+
print('[%d] %s: %s' % (i + 1, name, url))
57+
target = input('Choose dataset to download: ')
58+
target = int(target)
59+
60+
name, url = urls[target - 1]
61+
files = [
62+
'train-images-idx3-ubyte.gz',
63+
'train-labels-idx1-ubyte.gz',
64+
't10k-images-idx3-ubyte.gz',
65+
't10k-labels-idx1-ubyte.gz',
66+
]
67+
download(name, url, files)
68+
5269

5370
if __name__ == '__main__':
5471
main()

0 commit comments

Comments
 (0)