2017/10/30
Python - numpy 的使用方法
markdown
[NumPy Reference](https://docs.scipy.org/doc/numpy-1.13.0/reference/index.html)
數列生成
```
>>> np.zeros(5)
#array([ 0., 0., 0., 0., 0.])
>>> np.ones(5)
#array([ 1., 1., 1., 1., 1.])
>>> np.arange(5)
#array([0, 1, 2, 3, 4])
```
[更多的數列生成](https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.array-creation.html)
數列變形
```
>>> np.arange(12)
#array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> np.arange(12).reshape(2,6)
#array([[ 0, 1, 2, 3, 4, 5],
# [ 6, 7, 8, 9, 10, 11]])
>>> np.arange(12).reshape(3,4)
#array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
>>> np.arange(12).reshape(4,3)
#array([[ 0, 1, 2],
# [ 3, 4, 5],
# [ 6, 7, 8],
# [ 9, 10, 11]])
>>> np.arange(12).reshape(6,2)
#array([[ 0, 1],
# [ 2, 3],
# [ 4, 5],
# [ 6, 7],
# [ 8, 9],
# [10, 11]])
>>> np.arange(12).reshape(12,1).flatten()
#array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
```
查看數列形狀
```
>>> np.arange(12).reshape(1,2,3,2)
#array([[[[ 0, 1],
# [ 2, 3],
# [ 4, 5]],
#
# [[ 6, 7],
# [ 8, 9],
# [10, 11]]]])
>>> np.arange(12).reshape(1,2,3,2).shape
#(1, 2, 3, 2)
```
[更多的數列操作](https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.array-manipulation.html)
2017/10/26
Rails - Apartment 的使用方法
markdown
#簡介
Apartment : [https://github.com/influitive/apartment](https://github.com/influitive/apartment)
這個套件的功能是讓你在 rails 可以透過切換 db schema,來存取不同的資料。
在 postgresql 中,預設的 schema 名稱為 public ,而所有的 table 都在 schema 'public' 下。
你可以簡單地把 schema 看成 namespace,在 apartment 中,這被稱為是 tenant。
#安裝步驟
請參考 : [https://github.com/influitive/apartment](https://github.com/influitive/apartment)
#使用方法
## 在 rails c 環境下
新增 tenant
```
Apartment::Tenant.create('abc')
```
這個指令會在 schema 'abc' 下複製 public 上的所有表格。所以 tenant 就是具有相同表格的 schema。
在以下的示範,看到 abc 的地方,代表的是要填入你的 schema name。
顯示目前所在的 tenant
```
Apartment::Tenant.current
# "public"
```
切換 tenant
```
Apartment::Tenant.switch!('abc')
Apartment::Tenant.current
# "abc"
Apartment::Tenant.switch!('public')
Apartment::Tenant.current
# "public"
Apartment::Tenant.switch('abc') do
Apartment::Tenant.current
# "abc"
end
Apartment::Tenant.current
# "public"
```
有暫時切換跟永久切換兩種
## 在 rails db 環境下
列出所有 schema
```
\dn
# List of schemas
# Name | Owner
#--------+----------
# public | postgres
# abc | etrex
# (2 rows)
```
顯示目前所在的 schema
```
SHOW search_path;
# search_path
#-----------------
# "$user", public
# (1 row)
```
切換 schema
```
SET search_path TO abc;
# SET
SET search_path TO 'abc';
# SET
```
字串要不要加引號都可以,當 search_path 的值不在 schema 的列表上時不會跳 error,可以想像成連接到一個空的 schema,而這樣並不代表新增了一個 schema。
在 select 的當下使用 schema
```
SELECT * FROM schema_name.table_name;
```
## 關於 excluded_models
在 apartment 提供的功能中有一個功能,這個功能是可以設定在切換 schema 的時候,讓某些表格不要被切換,也就是做成全域的表格。
舉例來說,假設我有兩個 table,是使用以下 code 所生成。
```
# 這裡是 bash
rails g model a
rails g model b a:references
rails db:migrate
```
然後我將 B 做成全域的表格
```
# 這裡是 /config/initializers/apartment.rb 約 18 行的位置
config.excluded_models = %w{ B }
```
然後建立一個 tenant 'abc' 並且切換過去,在這個環境下做測試
```
# 這裡是 rails c 環境下
Apartment::Tenant.create('abc')
Apartment::Tenant.switch!('abc')
```
對 A 做一些事情
```
A.count
# (3.8ms) SELECT COUNT(*) FROM "as"
# => 0
```
對 B 也做一些事情
```
B.count
# (0.5ms) SELECT COUNT(*) FROM "public"."bs"
# => 0
```
在這裡可以看到,當你對 B 進行操作時,其實是會強制加上 "public" 的,也就是說,對於 B ,不管在哪一個 tenant 下,都只會去存取 schema 'public' 下的表格,所以其他的 schema 的表格 bs 應該會都是空的。
嘗試在 tenant 'abc' 下新增資料
```
a = A.create()
# (0.2ms) BEGIN
# SQL (0.4ms) INSERT INTO "as" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2017-10-25 17:16:22.084365"], ["updated_at", "2017-10-25 17:16:22.084365"]]
b = B.create(a:a)
# (0.2ms) BEGIN
# SQL (1.5ms) INSERT INTO "public"."bs" ("a_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["a_id", 3], ["created_at", "2017-10-25 17:16:24.957753"], ["updated_at", "2017-10-25 17:16:24.957753"]]
# (0.2ms) ROLLBACK
#ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: insert or update on table "bs" violates foreign #key constraint "fk_rails_ddf8c0c4b5"
#DETAIL: Key (a_id)=(3) is not present in table "as".
#: INSERT INTO "public"."bs" ("a_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"
# from (irb):31
```
這時候出大問題了,因為 A 建立在 abc 下,但是 B 建立在 public 下。而 public.bs 有一個外來鍵限制是 a_id 必須要在 public.as 中有出現。
使用 [pgAdmin](https://www.pgadmin.org/) 連進去看,對 db_name/Schemas/public/Tables/bs/Constraints/fk_rails_ddf8c04b5 按右鍵選 CREATE Script:
。
會看到生成的 script 內容為:
```
-- Constraint: fk_rails_ddf8c0c4b5
-- ALTER TABLE public.bs DROP CONSTRAINT fk_rails_ddf8c0c4b5;
ALTER TABLE public.bs
ADD CONSTRAINT fk_rails_ddf8c0c4b5 FOREIGN KEY (a_id)
REFERENCES public."as" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION;
```
在這裡明確地指出跟 public.bs 有關係的表格是 public.as ,而不是其他 schema 下的 as,但是 Apartment 不處理,所以會出問題。
2017/10/19
Network debug 方法
markdown
## linux 環境下
查詢所有 process
```
ps
```
輸出
```
PID TTY TIME CMD
21968 ttys000 0:00.16 -bash
```
查詢 port 3000 被誰占用
```
lsof -i :3000
```
輸出
```
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 20308 etrex 25u IPv4 0xd000000000000 0t0 TCP *:hbci (LISTEN)
```
刪除某個 process
```
kill 20308
```
強制刪除某個 process
```
kill -9 20308
```
## 參考文件
kill process:[https://blog.gtwang.org/linux/linux-kill-killall-xkill/](https://blog.gtwang.org/linux/linux-kill-killall-xkill/)
Ruby - RSpec 的使用方法
markdown
## RSpec 簡介
RSpec 在執行的時候不保證執行順序,每個測試產生的資料不會自動被清除。
新增測試的generator語法:
```
rails generate rspec:model user
```
這樣寫會建立一個檔案在 spec/models/user_spec.rb
執行測試的指令是在 rails 專案目錄下輸入以下指令:
```
# 這裡是 bash
# 執行所有測試
rspec
# 執行某個資料夾下的所有測試
rspec ./spec/models
# 執行某個檔案裡的所有測試
rspec ./spec/models/user_spec.rb
# 執行某個檔案裡的某個測試
rspec ./spec/models/user_spec.rb:8
```
簡單的範例
```
require 'rails_helper'
RSpec.describe "規格說明" do
describe "處於某個狀態下" do
# 設定狀態變數
let(:a) { 1 }
it "should be 1" do
puts "should be 1"
expect(a).to eq(1)
end
end
end
```
let 在每次測試裡,第一次存取變數時就會執行對應的程式
```
require 'rails_helper'
RSpec.describe "規格說明" do
describe "處於某個狀態下" do
let(:a) { puts "let a"; 1 }
it "1" do
puts "1"
puts "a=#{a}"
end
it "2" do
puts "2"
puts "a=#{a}"
puts "a=#{a}"
puts "a=#{a}"
end
end
end
```
輸出
```
1
let a
a=1
.2
let a
a=1
a=1
a=1
.
```
before 和 after 會在所有測試的執行前後做事
```
RSpec.describe "規格說明" do
describe "處於某個狀態下" do
before { puts "before" }
after { puts "after" }
it "1" do
puts "1"
end
it "2" do
puts "2"
end
end
end
```
執行結果
```
before
1
after
.before
2
after
.
```
因為測試對資料庫的操作會互相影響,如果想要確保每個測試都是在資料庫乾淨的狀態下,可以使用 [database_cleaner](https://github.com/DatabaseCleaner/database_cleaner)。
```
require 'database_cleaner'
...
RSpec.configure do |config|
...
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
...
end
```
其中的 before、around 可以參考官網說明文件:[https://relishapp.com/rspec/rspec-core/v/2-13/docs/hooks/before-and-after-hooks#before/after-blocks-defined-in-config-are-run-in-order](https://relishapp.com/rspec/rspec-core/v/2-13/docs/hooks/before-and-after-hooks#before/after-blocks-defined-in-config-are-run-in-order)
如果想要控制 rspec 執行每一個 test 的順序,可以這樣寫:
```
# 這裡是 bash
rspec --order defined
rspec --seed 1
```
詳細的介紹可以參考 [https://relishapp.com/rspec/rspec-core/docs/command-line/order](https://relishapp.com/rspec/rspec-core/docs/command-line/order)
如果想要把結果輸出到檔案,可以這樣寫:
```
# 這裡是 bash
rspec --out result.txt
rspec --format documentation --out result.txt
```
上面兩行會使檔案內容不同,詳細的介紹可以參考 [https://relishapp.com/rspec/rspec-core/v/2-4/docs/command-line/format-option](https://relishapp.com/rspec/rspec-core/v/2-4/docs/command-line/format-option)
Ruby - debug 方法
markdown
## 查詢繼承關係
```
File.ancestors
# [File, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]
```
## 從物件找方法
```
# 查 File 的類別方法
File.methods
# 查 File 的實體方法
File.instance_methods
# 查 File 的實體方法
File.new('/').methods
# 取得繼承樹上所有的方法
File.methods(true)
# 只取得屬於 File 的方法
File.methods(false)
```
## 從方法找定義
```
File.method(:read)
# #Method: File(IO).read
IO.method(:read)
# #Method: IO.read
IO.method(:read).source_location
# nil
```
因為 IO.read 的定義是寫在 c 語言,所以就不顯示了。
## 參考文件
為什麼File.method(:read)是nil:[https://ja.stackoverflow.com/questions/5755/ruby-file-read-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E8%AA%AC%E6%98%8E%E3%82%92api%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%81%A7%E8%AA%BF%E3%81%B9%E3%81%9F%E3%81%84](https://ja.stackoverflow.com/questions/5755/ruby-file-read-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E8%AA%AC%E6%98%8E%E3%82%92api%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%81%A7%E8%AA%BF%E3%81%B9%E3%81%9F%E3%81%84)
Python - 電腦字體數字辨識
markdown
續前篇:[Python - draw text on image and image to numpy array](http://etrex.blogspot.tw/2017/10/python-draw-text-on-image-and-image-to.html)
## 目標
嘗試建立一個簡單的類神經網路,只針對電腦字體數字 0~9 共 10 張圖片作訓練,訓練資料就是測試資料,在 40 次左右的訓練後正確度可達到 100%。
## 本文包含
* keras 的使用
* keras Model 輸出成圖片
## 程式碼
```
import numpy as np
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
image_size = (8,13)
font_size = 10
x_train = np.array([])
y_train = np.array([])
for i in range(10):
# 空白圖片生成
image = Image.new('L', image_size, 0)
# 取得繪圖器
draw = ImageDraw.Draw(image)
# 字型設定
# font = ImageFont.truetype("C:/Windows/Fonts/cour.ttf", font_size)
font = ImageFont.truetype("C:/Windows/Fonts/msjh.ttc", font_size)
# 關閉反鋸齒
draw.fontmode = '1'
# 測量文字尺寸
text_size = draw.textsize(str(i),font)
# print('text_size:', text_size)
# 文字置中
text_position = ((image_size[0]-text_size[0])//2,(image_size[1]-text_size[1])//2)
# print('text_position:', text_position)
# 畫上文字
draw.text(text_position, str(i), 255, font)
# 存檔
image.save(str(i)+'.bmp')
# 轉成 numpy array
na = np.array(image.getdata()).reshape(image.size[1], image.size[0])
# 加入訓練資料
x_train = np.append(x_train,na)
y_train = np.append(y_train,i)
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import RMSprop
# 每次更新時所採用的資料筆數
batch_size = 1
# 總共有幾種數字
num_classes = 10
# 要更新幾次
epochs = 100
# 把資料轉成 model 需要的格式
x_train = x_train.reshape(10, 104)
x_train = x_train.astype('float32')
x_train /= 255
print(x_train.shape[0], 'train samples')
y_train = keras.utils.to_categorical(y_train, num_classes)
# 建立 model
model = Sequential()
# 一層 + softmax
model.add(Dense(num_classes, input_shape=(104,), activation='softmax'))
# ??
model.summary()
# 選擇 loss function 和 optimizer
model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(),
metrics=['accuracy'])
# 開始訓練
history = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_train, y_train))
# 計算分數
score = model.evaluate(x_train, y_train, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
# 儲存 model 至圖片
from keras.utils import plot_model
plot_model(model, to_file='model.png')
```
## 輸出
```
Using TensorFlow backend.
10 train samples
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 10) 1050
=================================================================
Total params: 1,050
Trainable params: 1,050
Non-trainable params: 0
_________________________________________________________________
Train on 10 samples, validate on 10 samples
Epoch 1/100
10/10 [==============================] - ETA: 0s - loss: 2.5473 - acc: 0.0000e+00 - val_loss: 2.4555 - val_acc: 0.1000
Epoch 2/100
10/10 [==============================] - ETA: 0s - loss: 2.4563 - acc: 0.1000 - val_loss: 2.3924 - val_acc: 0.1000
Epoch 3/100
10/10 [==============================] - ETA: 0s - loss: 2.3926 - acc: 0.1000 - val_loss: 2.3334 - val_acc: 0.2000
Epoch 4/100
10/10 [==============================] - ETA: 0s - loss: 2.3336 - acc: 0.2000 - val_loss: 2.2760 - val_acc: 0.2000
Epoch 5/100
10/10 [==============================] - ETA: 0s - loss: 2.2766 - acc: 0.2000 - val_loss: 2.2196 - val_acc: 0.2000
Epoch 6/100
10/10 [==============================] - ETA: 0s - loss: 2.2203 - acc: 0.2000 - val_loss: 2.1636 - val_acc: 0.4000
Epoch 7/100
10/10 [==============================] - ETA: 0s - loss: 2.1640 - acc: 0.4000 - val_loss: 2.1090 - val_acc: 0.5000
Epoch 8/100
10/10 [==============================] - ETA: 0s - loss: 2.1096 - acc: 0.4000 - val_loss: 2.0545 - val_acc: 0.5000
Epoch 9/100
10/10 [==============================] - ETA: 0s - loss: 2.0556 - acc: 0.5000 - val_loss: 2.0013 - val_acc: 0.5000
Epoch 10/100
10/10 [==============================] - ETA: 0s - loss: 2.0023 - acc: 0.5000 - val_loss: 1.9484 - val_acc: 0.5000
Epoch 11/100
10/10 [==============================] - ETA: 0s - loss: 1.9493 - acc: 0.5000 - val_loss: 1.8971 - val_acc: 0.5000
Epoch 12/100
10/10 [==============================] - ETA: 0s - loss: 1.8985 - acc: 0.5000 - val_loss: 1.8453 - val_acc: 0.5000
Epoch 13/100
10/10 [==============================] - ETA: 0s - loss: 1.8464 - acc: 0.5000 - val_loss: 1.7949 - val_acc: 0.5000
Epoch 14/100
10/10 [==============================] - ETA: 0s - loss: 1.7962 - acc: 0.5000 - val_loss: 1.7448 - val_acc: 0.5000
Epoch 15/100
10/10 [==============================] - ETA: 0s - loss: 1.7464 - acc: 0.5000 - val_loss: 1.6958 - val_acc: 0.5000
Epoch 16/100
10/10 [==============================] - ETA: 0s - loss: 1.6971 - acc: 0.5000 - val_loss: 1.6471 - val_acc: 0.5000
Epoch 17/100
10/10 [==============================] - ETA: 0s - loss: 1.6486 - acc: 0.5000 - val_loss: 1.5994 - val_acc: 0.5000
Epoch 18/100
10/10 [==============================] - ETA: 0s - loss: 1.6007 - acc: 0.5000 - val_loss: 1.5520 - val_acc: 0.7000
Epoch 19/100
10/10 [==============================] - ETA: 0s - loss: 1.5538 - acc: 0.7000 - val_loss: 1.5064 - val_acc: 0.7000
Epoch 20/100
10/10 [==============================] - ETA: 0s - loss: 1.5078 - acc: 0.7000 - val_loss: 1.4612 - val_acc: 0.7000
Epoch 21/100
10/10 [==============================] - ETA: 0s - loss: 1.4629 - acc: 0.7000 - val_loss: 1.4168 - val_acc: 0.7000
Epoch 22/100
10/10 [==============================] - ETA: 0s - loss: 1.4190 - acc: 0.7000 - val_loss: 1.3736 - val_acc: 0.7000
Epoch 23/100
10/10 [==============================] - ETA: 0s - loss: 1.3758 - acc: 0.7000 - val_loss: 1.3311 - val_acc: 0.8000
Epoch 24/100
10/10 [==============================] - ETA: 0s - loss: 1.3331 - acc: 0.8000 - val_loss: 1.2891 - val_acc: 0.8000
Epoch 25/100
10/10 [==============================] - ETA: 0s - loss: 1.2913 - acc: 0.8000 - val_loss: 1.2488 - val_acc: 0.9000
Epoch 26/100
10/10 [==============================] - ETA: 0s - loss: 1.2513 - acc: 0.9000 - val_loss: 1.2091 - val_acc: 0.9000
Epoch 27/100
10/10 [==============================] - ETA: 0s - loss: 1.2114 - acc: 0.9000 - val_loss: 1.1701 - val_acc: 0.9000
Epoch 28/100
10/10 [==============================] - ETA: 0s - loss: 1.1721 - acc: 0.9000 - val_loss: 1.1324 - val_acc: 0.9000
Epoch 29/100
10/10 [==============================] - ETA: 0s - loss: 1.1349 - acc: 0.9000 - val_loss: 1.0957 - val_acc: 0.9000
Epoch 30/100
10/10 [==============================] - ETA: 0s - loss: 1.0984 - acc: 0.9000 - val_loss: 1.0596 - val_acc: 0.9000
Epoch 31/100
10/10 [==============================] - ETA: 0s - loss: 1.0620 - acc: 0.9000 - val_loss: 1.0243 - val_acc: 0.9000
Epoch 32/100
10/10 [==============================] - ETA: 0s - loss: 1.0269 - acc: 0.9000 - val_loss: 0.9905 - val_acc: 1.0000
Epoch 33/100
10/10 [==============================] - ETA: 0s - loss: 0.9932 - acc: 1.0000 - val_loss: 0.9571 - val_acc: 1.0000
Epoch 34/100
10/10 [==============================] - ETA: 0s - loss: 0.9597 - acc: 1.0000 - val_loss: 0.9247 - val_acc: 1.0000
Epoch 35/100
10/10 [==============================] - ETA: 0s - loss: 0.9276 - acc: 1.0000 - val_loss: 0.8934 - val_acc: 1.0000
Epoch 36/100
10/10 [==============================] - ETA: 0s - loss: 0.8962 - acc: 1.0000 - val_loss: 0.8629 - val_acc: 1.0000
Epoch 37/100
10/10 [==============================] - ETA: 0s - loss: 0.8655 - acc: 1.0000 - val_loss: 0.8330 - val_acc: 1.0000
Epoch 38/100
10/10 [==============================] - ETA: 0s - loss: 0.8359 - acc: 1.0000 - val_loss: 0.8047 - val_acc: 1.0000
Epoch 39/100
10/10 [==============================] - ETA: 0s - loss: 0.8077 - acc: 1.0000 - val_loss: 0.7766 - val_acc: 1.0000
Epoch 40/100
10/10 [==============================] - ETA: 0s - loss: 0.7797 - acc: 1.0000 - val_loss: 0.7501 - val_acc: 1.0000
Epoch 41/100
10/10 [==============================] - ETA: 0s - loss: 0.7529 - acc: 1.0000 - val_loss: 0.7239 - val_acc: 1.0000
Epoch 42/100
10/10 [==============================] - ETA: 0s - loss: 0.7270 - acc: 1.0000 - val_loss: 0.6988 - val_acc: 1.0000
Epoch 43/100
10/10 [==============================] - ETA: 0s - loss: 0.7018 - acc: 1.0000 - val_loss: 0.6744 - val_acc: 1.0000
Epoch 44/100
10/10 [==============================] - ETA: 0s - loss: 0.6773 - acc: 1.0000 - val_loss: 0.6511 - val_acc: 1.0000
Epoch 45/100
10/10 [==============================] - ETA: 0s - loss: 0.6542 - acc: 1.0000 - val_loss: 0.6283 - val_acc: 1.0000
Epoch 46/100
10/10 [==============================] - ETA: 0s - loss: 0.6312 - acc: 1.0000 - val_loss: 0.6065 - val_acc: 1.0000
Epoch 47/100
10/10 [==============================] - ETA: 0s - loss: 0.6097 - acc: 1.0000 - val_loss: 0.5852 - val_acc: 1.0000
Epoch 48/100
10/10 [==============================] - ETA: 0s - loss: 0.5882 - acc: 1.0000 - val_loss: 0.5647 - val_acc: 1.0000
Epoch 49/100
10/10 [==============================] - ETA: 0s - loss: 0.5677 - acc: 1.0000 - val_loss: 0.5451 - val_acc: 1.0000
Epoch 50/100
10/10 [==============================] - ETA: 0s - loss: 0.5482 - acc: 1.0000 - val_loss: 0.5261 - val_acc: 1.0000
Epoch 51/100
10/10 [==============================] - ETA: 0s - loss: 0.5291 - acc: 1.0000 - val_loss: 0.5078 - val_acc: 1.0000
Epoch 52/100
10/10 [==============================] - ETA: 0s - loss: 0.5108 - acc: 1.0000 - val_loss: 0.4900 - val_acc: 1.0000
Epoch 53/100
10/10 [==============================] - ETA: 0s - loss: 0.4928 - acc: 1.0000 - val_loss: 0.4729 - val_acc: 1.0000
Epoch 54/100
10/10 [==============================] - ETA: 0s - loss: 0.4759 - acc: 1.0000 - val_loss: 0.4567 - val_acc: 1.0000
Epoch 55/100
10/10 [==============================] - ETA: 0s - loss: 0.4596 - acc: 1.0000 - val_loss: 0.4409 - val_acc: 1.0000
Epoch 56/100
10/10 [==============================] - ETA: 0s - loss: 0.4440 - acc: 1.0000 - val_loss: 0.4258 - val_acc: 1.0000
Epoch 57/100
10/10 [==============================] - ETA: 0s - loss: 0.4286 - acc: 1.0000 - val_loss: 0.4113 - val_acc: 1.0000
Epoch 58/100
10/10 [==============================] - ETA: 0s - loss: 0.4143 - acc: 1.0000 - val_loss: 0.3971 - val_acc: 1.0000
Epoch 59/100
10/10 [==============================] - ETA: 0s - loss: 0.4001 - acc: 1.0000 - val_loss: 0.3835 - val_acc: 1.0000
Epoch 60/100
10/10 [==============================] - ETA: 0s - loss: 0.3864 - acc: 1.0000 - val_loss: 0.3706 - val_acc: 1.0000
Epoch 61/100
10/10 [==============================] - ETA: 0s - loss: 0.3735 - acc: 1.0000 - val_loss: 0.3580 - val_acc: 1.0000
Epoch 62/100
10/10 [==============================] - ETA: 0s - loss: 0.3611 - acc: 1.0000 - val_loss: 0.3459 - val_acc: 1.0000
Epoch 63/100
10/10 [==============================] - ETA: 0s - loss: 0.3487 - acc: 1.0000 - val_loss: 0.3343 - val_acc: 1.0000
Epoch 64/100
10/10 [==============================] - ETA: 0s - loss: 0.3370 - acc: 1.0000 - val_loss: 0.3232 - val_acc: 1.0000
Epoch 65/100
10/10 [==============================] - ETA: 0s - loss: 0.3261 - acc: 1.0000 - val_loss: 0.3125 - val_acc: 1.0000
Epoch 66/100
10/10 [==============================] - ETA: 0s - loss: 0.3152 - acc: 1.0000 - val_loss: 0.3023 - val_acc: 1.0000
Epoch 67/100
10/10 [==============================] - ETA: 0s - loss: 0.3049 - acc: 1.0000 - val_loss: 0.2925 - val_acc: 1.0000
Epoch 68/100
10/10 [==============================] - ETA: 0s - loss: 0.2953 - acc: 1.0000 - val_loss: 0.2828 - val_acc: 1.0000
Epoch 69/100
10/10 [==============================] - ETA: 0s - loss: 0.2854 - acc: 1.0000 - val_loss: 0.2736 - val_acc: 1.0000
Epoch 70/100
10/10 [==============================] - ETA: 0s - loss: 0.2762 - acc: 1.0000 - val_loss: 0.2648 - val_acc: 1.0000
Epoch 71/100
10/10 [==============================] - ETA: 0s - loss: 0.2675 - acc: 1.0000 - val_loss: 0.2563 - val_acc: 1.0000
Epoch 72/100
10/10 [==============================] - ETA: 0s - loss: 0.2588 - acc: 1.0000 - val_loss: 0.2481 - val_acc: 1.0000
Epoch 73/100
10/10 [==============================] - ETA: 0s - loss: 0.2506 - acc: 1.0000 - val_loss: 0.2403 - val_acc: 1.0000
Epoch 74/100
10/10 [==============================] - ETA: 0s - loss: 0.2429 - acc: 1.0000 - val_loss: 0.2327 - val_acc: 1.0000
Epoch 75/100
10/10 [==============================] - ETA: 0s - loss: 0.2351 - acc: 1.0000 - val_loss: 0.2254 - val_acc: 1.0000
Epoch 76/100
10/10 [==============================] - ETA: 0s - loss: 0.2279 - acc: 1.0000 - val_loss: 0.2184 - val_acc: 1.0000
Epoch 77/100
10/10 [==============================] - ETA: 0s - loss: 0.2209 - acc: 1.0000 - val_loss: 0.2117 - val_acc: 1.0000
Epoch 78/100
10/10 [==============================] - ETA: 0s - loss: 0.2140 - acc: 1.0000 - val_loss: 0.2053 - val_acc: 1.0000
Epoch 79/100
10/10 [==============================] - ETA: 0s - loss: 0.2078 - acc: 1.0000 - val_loss: 0.1989 - val_acc: 1.0000
Epoch 80/100
10/10 [==============================] - ETA: 0s - loss: 0.2011 - acc: 1.0000 - val_loss: 0.1929 - val_acc: 1.0000
Epoch 81/100
10/10 [==============================] - ETA: 0s - loss: 0.1954 - acc: 1.0000 - val_loss: 0.1872 - val_acc: 1.0000
Epoch 82/100
10/10 [==============================] - ETA: 0s - loss: 0.1894 - acc: 1.0000 - val_loss: 0.1817 - val_acc: 1.0000
Epoch 83/100
10/10 [==============================] - ETA: 0s - loss: 0.1841 - acc: 1.0000 - val_loss: 0.1763 - val_acc: 1.0000
Epoch 84/100
10/10 [==============================] - ETA: 0s - loss: 0.1784 - acc: 1.0000 - val_loss: 0.1711 - val_acc: 1.0000
Epoch 85/100
10/10 [==============================] - ETA: 0s - loss: 0.1732 - acc: 1.0000 - val_loss: 0.1662 - val_acc: 1.0000
Epoch 86/100
10/10 [==============================] - ETA: 0s - loss: 0.1684 - acc: 1.0000 - val_loss: 0.1614 - val_acc: 1.0000
Epoch 87/100
10/10 [==============================] - ETA: 0s - loss: 0.1636 - acc: 1.0000 - val_loss: 0.1568 - val_acc: 1.0000
Epoch 88/100
10/10 [==============================] - ETA: 0s - loss: 0.1590 - acc: 1.0000 - val_loss: 0.1523 - val_acc: 1.0000
Epoch 89/100
10/10 [==============================] - ETA: 0s - loss: 0.1542 - acc: 1.0000 - val_loss: 0.1480 - val_acc: 1.0000
Epoch 90/100
10/10 [==============================] - ETA: 0s - loss: 0.1501 - acc: 1.0000 - val_loss: 0.1438 - val_acc: 1.0000
Epoch 91/100
10/10 [==============================] - ETA: 0s - loss: 0.1457 - acc: 1.0000 - val_loss: 0.1399 - val_acc: 1.0000
Epoch 92/100
10/10 [==============================] - ETA: 0s - loss: 0.1418 - acc: 1.0000 - val_loss: 0.1360 - val_acc: 1.0000
Epoch 93/100
10/10 [==============================] - ETA: 0s - loss: 0.1379 - acc: 1.0000 - val_loss: 0.1323 - val_acc: 1.0000
Epoch 94/100
10/10 [==============================] - ETA: 0s - loss: 0.1343 - acc: 1.0000 - val_loss: 0.1287 - val_acc: 1.0000
Epoch 95/100
10/10 [==============================] - ETA: 0s - loss: 0.1306 - acc: 1.0000 - val_loss: 0.1252 - val_acc: 1.0000
Epoch 96/100
10/10 [==============================] - ETA: 0s - loss: 0.1271 - acc: 1.0000 - val_loss: 0.1218 - val_acc: 1.0000
Epoch 97/100
10/10 [==============================] - ETA: 0s - loss: 0.1237 - acc: 1.0000 - val_loss: 0.1185 - val_acc: 1.0000
Epoch 98/100
10/10 [==============================] - ETA: 0s - loss: 0.1204 - acc: 1.0000 - val_loss: 0.1154 - val_acc: 1.0000
Epoch 99/100
10/10 [==============================] - ETA: 0s - loss: 0.1172 - acc: 1.0000 - val_loss: 0.1124 - val_acc: 1.0000
Epoch 100/100
10/10 [==============================] - ETA: 0s - loss: 0.1141 - acc: 1.0000 - val_loss: 0.1095 - val_acc: 1.0000
Test loss: 0.109465420246
Test accuracy: 1.0
```
## 輸出的圖片
plot_model 的執行,需要安裝 pydot 和 graphviz
```
pip3 install pydot
```
## plot_model 的環境安裝
在 windows 上,graphviz 必須手動安裝,安裝檔可以到他們官網下載。
[http://www.graphviz.org/Download_windows.php](http://www.graphviz.org/Download_windows.php)
安裝好之後必須在環境變數 path 加上 C:\Program Files (x86)\Graphviz2.30\bin 才能使用。
cmd 下輸入指令:
```
dot -version
```
若顯示以下訊息,表示正確安裝。
```
dot - graphviz version 2.30.1 (20130214.1330)
libdir = "C:\Program Files (x86)\Graphviz2.30\bin"
Activated plugin library: gvplugin_pango.dll
Using textlayout: textlayout:cairo
Activated plugin library: gvplugin_dot_layout.dll
Using layout: dot:dot_layout
Activated plugin library: gvplugin_core.dll
Using render: dot:core
Using device: dot:dot:core
The plugin configuration file:
C:\Program Files (x86)\Graphviz2.30\bin\config6
was successfully loaded.
render : cairo dot fig gd gdiplus map pic pov ps svg tk vml vrml xdot
layout : circo dot fdp neato nop nop1 nop2 osage patchwork sfdp twopi
textlayout : textlayout
device : bmp canon cmap cmapx cmapx_np dot emf emfplus eps fig gd gd2 gif gv imap imap_np ismap jpe jpeg jpg metafile pdf p
ic plain plain-ext png pov ps ps2 svg svgz tif tiff tk vml vmlz vrml wbmp xdot
loadimage : (lib) bmp eps gd gd2 gif jpe jpeg jpg png ps svg
```
## 參考文件
plot_model 在 windows 上的環境建立:[https://zhuanlan.zhihu.com/p/28158957](https://zhuanlan.zhihu.com/p/28158957)
graphviz 的使用:[https://www.openfoundry.org/tw/foss-programs/8820-graphviz-](https://www.openfoundry.org/tw/foss-programs/8820-graphviz-)
2017/10/17
Python - draw text on image and image to numpy array
markdown
## 目標
嘗試生成以微軟正黑體寫成的數字0~9並轉換成 numpy array
##本文包含
* 生成圖片和保存圖片
* 在圖片上寫出指定字型和大小的字
* 設定反鋸齒模式
* 圖片轉成 numpy array
## 程式碼
```
import numpy
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
image_size = (8,13)
font_size = 10
for i in range(10):
# 空白圖片生成
image = Image.new('L', image_size, 0)
# 取得繪圖器
draw = ImageDraw.Draw(image)
# 微軟正黑體
font = ImageFont.truetype("C:/Windows/Fonts/msjh.ttc", font_size)
# 關閉反鋸齒
draw.fontmode = '1'
# 測量文字尺寸
text_size = draw.textsize(str(i),font)
# print('text_size:', text_size)
# 文字置中
text_position = ((image_size[0]-text_size[0])//2,(image_size[1]-text_size[1])//2)
# print('text_position:', text_position)
# 畫上文字
draw.text(text_position, str(i), 255, font)
# 存檔
image.save(str(i)+'.bmp')
# 轉成 numpy array
na = numpy.array(image.getdata()).reshape(image.size[1], image.size[0])
# 印出
print(na)
```
## 輸出
```
Using TensorFlow backend.
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 255 255 255 255 0 0]
[ 0 0 255 0 0 255 255 0]
[ 0 255 0 0 0 0 255 0]
[ 0 255 0 0 0 0 255 0]
[ 0 255 0 0 0 0 255 0]
[ 0 255 0 0 0 0 255 0]
[ 0 255 255 0 0 255 0 0]
[ 0 0 255 255 255 255 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 255 255 0 0 0]
[ 0 0 255 255 255 0 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 255 255 255 255 255 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 255 255 255 0 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 0 0 0 0 255 0]
[ 0 0 0 0 0 0 255 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 0 255 0 0 0 0]
[ 0 0 255 255 255 255 255 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 255 255 0 0 0]
[ 0 0 255 0 0 255 0 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 255 255 0 0 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 255 0 0 255 0 0]
[ 0 0 255 255 255 0 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 255 255 0 0]
[ 0 0 0 0 255 255 0 0]
[ 0 0 0 255 0 255 0 0]
[ 0 0 255 0 0 255 0 0]
[ 0 255 0 0 0 255 0 0]
[ 0 255 255 255 255 255 255 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 255 255 255 255 0 0]
[ 0 0 255 0 0 0 0 0]
[ 0 0 255 0 0 0 0 0]
[ 0 0 255 255 255 0 0 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 255 0 0 255 0 0]
[ 0 0 255 255 255 0 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 255 255 255 0]
[ 0 0 0 255 0 0 0 0]
[ 0 0 255 0 0 0 0 0]
[ 0 0 255 0 255 255 0 0]
[ 0 0 255 255 0 0 255 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 0 255 255 255 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 255 255 255 255 255 255 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 0 0 255 0 0 0]
[ 0 0 0 255 0 0 0 0]
[ 0 0 0 255 0 0 0 0]
[ 0 0 255 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 255 255 0 0 0]
[ 0 0 255 0 0 255 0 0]
[ 0 0 255 0 0 255 0 0]
[ 0 0 0 255 255 0 0 0]
[ 0 0 0 255 0 255 0 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 0 255 255 255 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 255 255 255 0 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 255 0 0 0 255 0]
[ 0 0 0 255 255 255 255 0]
[ 0 0 0 0 0 0 255 0]
[ 0 0 0 0 0 255 0 0]
[ 0 0 255 255 255 0 0 0]
[ 0 0 0 0 0 0 0 0]]
```
## 參考文件
PIL影像相關:[http://pillow.readthedocs.io/en/stable/reference/index.html](http://pillow.readthedocs.io/en/stable/reference/index.html)
2017/10/13
Python - 印出 mnist 的手寫圖形
markdown
## 安裝 keras
請參考
[https://etrex.blogspot.tw/2017/10/windows-10-keras.html](https://etrex.blogspot.tw/2017/10/windows-10-keras.html)
## 安裝 PIL
在 cmd 輸入以下指令:
```
pip3 install Image
```
若想查看已安裝了哪些套件,可在 cmd 輸入以下指令:
```
pip3 list
```
## 印出 MNIST 的手寫數字圖形
[MNIST](http://yann.lecun.com/exdb/mnist/) 是一個知名的手寫數字資料集,被當作機器學習界的 hello world 來使用。
```
import keras
from keras.datasets import mnist
from PIL import Image
(x_train, y_train), (x_test, y_test) = mnist.load_data()
Image.fromarray(x_train[0,]).show()
```
x_train 是一個大小為 60000,28,28 的三維陣列,代表 60000 張 28x28 的灰階圖檔。
可輸入以下指令查看:
```
x_train.shape
# (60000,28,28)
```
x_train[0,] 是一個大小為 28,28 的二維陣列,代表第一張圖片。
Image.fromarray(x_train[0,]).show() 把代表第一張圖片的二維陣列轉為圖片並顯示。
Python - debug 方法
印出變數值
```
a = 1
print(a)
# 1
```
印出變數型態
```
a = 1
print(type(a))
#
```
印出變數成員
```
a = 1
print(dir(a))
# ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
```
印出模組成員
```
import json
dir(json)
# ['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_encoder', 'decoder', 'dump', 'dumps', 'encoder', 'load', 'loads', 'scanner']
```
呼叫成員
```
a = -1
print(a.__abs__)
#
print(a.__abs__())
# -1
```
印出json
```
import json
print(json.dumps([1, 2, 3]))
# '[1, 2, 3]'
```
JS - 重複組合
給兩個序列 a 跟 b ,在不改變 a 和 b 序列順序的情況下,列出所有 a 跟 b 混合後的結果
使用[重複組合](https://zh.wikipedia.org/wiki/%E7%B5%84%E5%90%88#.E9.87.8D.E8.A4.87.E7.B5.84.E5.90.88.E7.90.86.E8.AB.96.E8.88.87.E5.85.AC.E5.BC.8F)的概念,兩個序列混合後的結果等同於其中一個序列的 index 的組合
舉例來說序列 a 為 `--`,序列 b 為 `**`,其所有混和結果為:
```
--**
-*-*
*--*
-**-
*-*-
**--
```
共六種,而我們可以把 a 序列所在的 index 寫出:
```
1,2
1,3
2,3
1,4
2,4
3,4
```
而這是 C4取2 的所有組合結果。
假設已知 b 序列長度為 6,我們可以使用迴圈生成組合。
```
var set = {
"a":['b','b','b','b'],
"b":['3','4','5','6','7','8']
}
var n = set['a'].length + set['b'].length;
var c = [];
for(var i1 = 0 ; i1 < n ; i1 ++)
for(var i2 = i1+1 ; i2 < n ; i2 ++)
for(var i3 = i2+1 ; i3 < n ; i3 ++)
for(var i4 = i3+1 ; i4 < n ; i4 ++)
for(var i5 = i4+1 ; i5 < n ; i5 ++)
for(var i6 = i5+1 ; i6 < n ; i6 ++){
var ab = [];
for(var i = 0 ; i < n ; i ++)
ab.push('a');
ab[i1] = 'b';
ab[i2] = 'b';
ab[i3] = 'b';
ab[i4] = 'b';
ab[i5] = 'b';
ab[i6] = 'b';
var c0 = [];
var index = {"a":0,"b":0};
for(var i = 0 ; i < n ; i ++){
c0.push(set[ab[i]][index[ab[i]]]);
index[ab[i]] = index[ab[i]] + 1;
}
c.push(c0);
console.log(c0);
}
```
2017/10/11
在 Windows 10 上安裝 Keras 的流程
markdown
Keras 是一個在 Python 上的深度學習工具,用這個工具可以快速打造出複雜的類神經網路結構
他需要用到 TensorFlow,所以在安裝 Keras 之前要先安裝 TensorFlow
在安裝 TensorFlow 之前要先安裝 Python 2.7 或 3.5。
##先裝 Python
我個人是安裝 Python 3.5,安裝流程請參考 [https://pygame.hackersir.org/Lessons/01/Python_install.html](https://pygame.hackersir.org/Lessons/01/Python_install.html),
正確安裝後,在 cmd 下輸入指令:
```
python -V
```
若顯示 Python 3.5.2 表示正確安裝。
##接著裝 TensorFlow
以下介紹cpu版本的安裝,若需要gpu版本的安裝流程請參考[https://rreadmorebooks.blogspot.tw/2017/04/win10cudacudnn.html](https://rreadmorebooks.blogspot.tw/2017/04/win10cudacudnn.html)
在 cmd 下輸入指令:
```
pip3 install --upgrade tensorflow
```
裝好後,接著輸入 python 進入互動模式:
```
python
```
再輸入以下的 python 程式碼(可直接複製貼上四行)
```
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
```
若顯示 b'Hello, TensorFlow!' 表示正確安裝,此時可輸入 exit() 離開 python 互動模式。
##SciPy
在裝 Keras 之前,可能需要手動裝 SciPy,因為 SciPy 的自動安裝流程在 Windows 上似乎不完整。
先開啟[http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy](http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy),
然後點選 scipy‑1.0.0rc1‑cp35‑cp35m‑win_amd64.whl 下載檔案。
下載好了之後,在 cmd 切換目錄至下載目錄,然後輸入指令:
```
pip3 install scipy‑1.0.0rc1‑cp35‑cp35m‑win_amd64.whl
```
##最後裝 Keras
直接在 cmd 輸入指令:
```
pip3 install keras
```
裝好後,接著輸入 python 進入互動模式:
```
python
```
再輸入以下的 python 程式碼
```
import keras
```
若顯示 Using TensorFlow backend. 表示正確安裝,此時可輸入 exit() 離開 python 互動模式。
##參考連結:
安裝 Python [https://pygame.hackersir.org/Lessons/01/Python_install.html](https://pygame.hackersir.org/Lessons/01/Python_install.html)
安裝 TensorFlow [https://www.tensorflow.org/install/install_windows](https://www.tensorflow.org/install/install_windows)
安裝 SciPy [http://codewenda.com/windows%E4%B8%8A%E4%BD%BF%E7%94%A8pip%E5%AE%89%E8%A3%85scipy%E9%94%99%E8%AF%AF%EF%BC%9Arunning-setup-py-bdist_wheel-for-scipy-error/](http://codewenda.com/windows%E4%B8%8A%E4%BD%BF%E7%94%A8pip%E5%AE%89%E8%A3%85scipy%E9%94%99%E8%AF%AF%EF%BC%9Arunning-setup-py-bdist_wheel-for-scipy-error/)
安裝 Keras [https://keras-cn.readthedocs.io/en/latest/#_2](https://keras-cn.readthedocs.io/en/latest/#_2)
安裝 nokogiri 失敗時的解決方法
(參考此篇文章)[https://github.com/sparklemotion/nokogiri/issues/1483]
在 bash 輸入 xcode-select --install 可解決問題。
在我的 macbook 上的錯誤訊息如下:
```
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: /Users/etrex/.rvm/gems/ruby-2.4.1@-global/gems/nokogiri-1.8.0/ext/nokogiri
/Users/etrex/.rvm/rubies/ruby-2.4.1/bin/ruby -r ./siteconf20171011-80748-pgpdll.rb extconf.rb
checking if the C compiler accepts ... yes
checking if the C compiler accepts -Wno-error=unused-command-line-argument-hard-error-in-future... no
Building nokogiri using packaged libraries.
Using mini_portile version 2.2.0
checking for iconv.h... yes
checking for gzdopen() in -lz... yes
checking for iconv using --with-opt-* flags... yes
************************************************************************
IMPORTANT NOTICE:
Building Nokogiri with a packaged version of libxml2-2.9.4
with the following patches applied:
- 0001-Fix-comparison-with-root-node-in-xmlXPathCmpNodes.patch
- 0002-Fix-XPointer-paths-beginning-with-range-to.patch
- 0003-Disallow-namespace-nodes-in-XPointer-ranges.patch
Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:
gem install nokogiri -- --use-system-libraries
[--with-xml2-config=/path/to/xml2-config]
[--with-xslt-config=/path/to/xslt-config]
If you are using Bundler, tell it to use the option:
bundle config build.nokogiri --use-system-libraries
bundle install
Note, however, that nokogiri is not fully compatible with arbitrary
versions of libxml2 provided by OS/package vendors.
************************************************************************
Extracting libxml2-2.9.4.tar.gz into tmp/x86_64-apple-darwin15.4.0/ports/libxml2/2.9.4... OK
Running git apply with /Users/etrex/.rvm/gems/ruby-2.4.1@-global/gems/nokogiri-1.8.0/patches/libxml2/0001-Fix-comparison-with-root-node-in-xmlXPathCmpNodes.patch... OK
Running git apply with /Users/etrex/.rvm/gems/ruby-2.4.1@-global/gems/nokogiri-1.8.0/patches/libxml2/0002-Fix-XPointer-paths-beginning-with-range-to.patch... OK
Running git apply with /Users/etrex/.rvm/gems/ruby-2.4.1@-global/gems/nokogiri-1.8.0/patches/libxml2/0003-Disallow-namespace-nodes-in-XPointer-ranges.patch... OK
Running 'configure' for libxml2 2.9.4... OK
Running 'compile' for libxml2 2.9.4... ERROR, review
'/Users/etrex/.rvm/gems/ruby-2.4.1@-global/gems/nokogiri-1.8.0/ext/nokogiri/tmp/x86_64-apple-darwin15.4.0/ports/libxml2/2.9.4/compile.log' to see what happened. Last lines are:
========================================================================
unsigned short* in = (unsigned short*) inb;
^~~~~~~~~~~~~~~~~~~~~
encoding.c:815:27: warning: cast from 'unsigned char *' to 'unsigned short *' increases required alignment from 1 to 2 [-Wcast-align]
unsigned short* out = (unsigned short*) outb;
^~~~~~~~~~~~~~~~~~~~~~
4 warnings generated.
CC error.lo
CC parserInternals.lo
CC parser.lo
CC tree.lo
CC hash.lo
CC list.lo
CC xmlIO.lo
xmlIO.c:1450:52: error: use of undeclared identifier 'LZMA_OK'
ret = (__libxml2_xzclose((xzFile) context) == LZMA_OK ) ? 0 : -1;
^
1 error generated.
make[2]: *** [xmlIO.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
========================================================================
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
```
訂閱:
文章 (Atom)