Last active
May 6, 2017 12:49
-
-
Save Clcanny/74d670cfb9447e2a9355d76026906b55 to your computer and use it in GitHub Desktop.
Machine Learning Programming Environment: python3.5 + tensorflow + keras
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: UTF-8 -*- | |
# 命名尽量采用LaTex的写法 | |
# M作为分隔符,起到空格的作用 | |
# _作为下标,__作为上标 | |
import numpy as np | |
# 读取测试数据 | |
test_data = np.genfromtxt('test_data.csv', delimiter=',', dtype=np.double) | |
test_targets = np.genfromtxt('test_targets.csv', delimiter='\n', dtype=np.double) | |
# 读取训练数据 | |
# train_data.shape = (3000, 400) | |
train_data = np.genfromtxt('train_data.csv', delimiter=',', dtype=np.double) | |
# train_targets.shpae = (3000,) | |
train_targets = np.genfromtxt('train_targets.csv', delimiter='\n', dtype=np.double) | |
train_targets = train_targets.reshape((train_targets.shape[0], 1)) | |
# train_targets.shape = (3000, 1) | |
# 输出结果是mulLyR | |
def num2class(vecLyR): | |
mulLyR = np.zeros(shape=(0,), dtype=np.double) | |
for y in vecLyR: | |
tmp = np.zeros(shape=(10,), dtype=np.double) | |
tmp[np.int(y)] = 1 | |
mulLyR = np.append(mulLyR, tmp) | |
mulLyR = mulLyR.reshape((vecLyR.shape[0], 10)) | |
return mulLyR | |
# 输出结果是vecLyR | |
def class2num(mulLyR): | |
vecLyR = np.zeros(shape=(0,), dtype=np.int) | |
for y in mulLyR: | |
vecLyR = np.append(vecLyR, np.nanargmax(y)) | |
return vecLyR | |
# 激活函数 | |
def sigmoid(x): | |
ret = np.exp(-1 * x) + 1 | |
return 1 / ret | |
# 更新公式辅助公式 | |
# scalar -> scalar -> scalar | |
def return_g_j(y_j__k, hatLyR_j__k): | |
return hatLyR_j__k * (1 - hatLyR_j__k) * (y_j__k - hatLyR_j__k) | |
# 更新公式辅助公式 | |
# scalar -> vector -> vector -> vector -> scalar | |
def return_e_h(b_h, vecLomega_hR, vecLyR, vecLhatLyRR): | |
# vecLomega_hR.shape = (10,) | |
# vecLyR.shape = (10,) | |
# vecLhatLyRR.shape = (10,) | |
vecLgR = np.zeros(shape=(0,), dtype=np.double) | |
for i in range(0, vecLyR.shape[0]): | |
g_j = return_g_j(vecLyR[i], vecLhatLyRR[i]) | |
vecLgR = np.append(vecLgR, g_j) | |
# vecLgR.shape = (10,) | |
return b_h * (1 - b_h) * np.dot(vecLomega_hR ,vecLgR) | |
# 更新公式 | |
def return_deltaMomega_LhjR(eta, g_i, b_h): | |
return eta * g_i * b_h | |
# 更新公式 | |
def return_deltaMtheta_j(eta, g_j): | |
return -1 * eta * g_j | |
# 更新公式 | |
def return_deltaMupsilon_LihR(eta, e_h, x_i): | |
return eta * e_h * x_i | |
# 更新公式 | |
def return_deltaMUpsilon_h(eta, e_h): | |
return -1 * eta * e_h | |
class Network: | |
def __init__(self, d, q, l): | |
self.d = d | |
self.q = q | |
self.l = l | |
self.Upsilon = np.full(shape=(self.q,), dtype=np.double, fill_value=0) | |
self.theta = np.full(shape=(self.l,), dtype=np.double, fill_value=0) | |
self.upsilon = np.full(shape=(self.q, self.d), dtype=np.double, fill_value=0) | |
for h in range(0, self.q): | |
for i in range(0, self.d): | |
self.upsilon[h][i] = np.random.uniform(-0.5, 0.5) | |
self.omega = np.full(shape=(self.l, self.q), dtype=np.double, fill_value=0) | |
for j in range(0, self.l): | |
for h in range(0, self.q): | |
self.upsilon[j][h] = np.random.uniform(-0.5, 0.5) | |
# vector -> (vector, vector) | |
def predict(self, vecLxR): | |
alpha = np.zeros(shape=(0,), dtype=np.double) | |
for h in range(0, self.q): | |
# 计算隐层的输入 | |
alpha_h = np.dot(self.upsilon[h], vecLxR) | |
# self.upsilon[h].shape = (self.d,) | |
# vecLxR.shape = (self.d,) | |
# 计算隐层的输出 | |
alpha_h = sigmoid(alpha_h - self.Upsilon[h]) | |
# self.Upsilon.shape = (self.q,) | |
alpha = np.append(alpha, alpha_h) | |
# alpha.shape = (self.q,) | |
beta = np.zeros(shape=(0,), dtype=np.double) | |
for j in range(0, self.l): | |
# 计算输出层的输入 | |
beta_j = np.dot(self.omega[j], alpha) | |
# self.omega[j].shape = (self.q,) | |
# alpha.shape = (self.q,) | |
# 计算输出层的输出 | |
beta_j = sigmoid(beta_j - self.theta[j]) | |
# self.theta.shape=(self.l,) | |
beta = np.append(beta, beta_j) | |
# beta.shape = (self.l,) | |
# alpha是隐层的输出,也就是vecLbR | |
# beta是输出层的输出,也就是vecLhatLyRR | |
return (alpha, beta); | |
def predictFaster(self, vecLxR): | |
mu = np.mat(self.upsilon) | |
mx = np.mat(vecLxR.reshape((-1, 1))) | |
alpha = sigmoid(np.array(mu * mx).flatten() - self.Upsilon) | |
mo = np.mat(self.omega) | |
ma = np.mat(alpha.reshape((-1, 1))) | |
beta = sigmoid(np.array(mo * ma).flatten() - self.theta) | |
return (alpha, beta) | |
def predicts(self, mulLxR): | |
mulLhatLyRR = np.zeros(shape=(0, self.l), dtype=np.double) | |
for k in range(0, mulLxR.shape[0]): | |
(_, vecLhatLyRR) = self.predict(mulLxR[k]) | |
mulLhatLyRR = np.append(mulLhatLyRR, vecLhatLyRR) | |
mulLhatLyRR = mulLhatLyRR.reshape((mulLxR.shape[0], self.l)) | |
return mulLhatLyRR | |
# 对一个数据做一次更新 | |
# 注意输入是两个向量 | |
def updateOnData(self, vecLxR, vecLyR, eta): | |
(vecLbR, vecLhatLyRR) = self.predict(vecLxR) | |
# vecLbR.shape = (self.q,) | |
# vecLhatLyRR.shape = (self.l,) | |
# self.theta.shape = (self.l,) | |
for j in range(0, self.l): | |
g_j = return_g_j(vecLyR[j], vecLhatLyRR[j]) | |
# return_g_j(y_j__k, hatLyR_j__k) | |
deltaMtheta_j = return_deltaMtheta_j(eta, g_j) | |
self.theta[j] += deltaMtheta_j | |
# self.Upsilon.shape = (self.q,) | |
for h in range(0, self.q): | |
e_h = return_e_h(vecLbR[h], self.omega[:, h], vecLyR, vecLhatLyRR) | |
# return_e_h(b_h, vecLomega_hR, vecLyR, vecLhatLyRR) | |
deltaMUpsilon_h = return_deltaMUpsilon_h(eta, e_h) | |
self.Upsilon[h] += deltaMUpsilon_h | |
# self.omega.shape = (self.l,, self.q) | |
for j in range(0, self.l): | |
for h in range(0, self.q): | |
g_j = return_g_j(vecLyR[j], vecLhatLyRR[j]) | |
deltaMomega_LhjR = return_deltaMomega_LhjR(eta, g_j, vecLbR[h]) | |
self.omega[j][h] += deltaMomega_LhjR | |
# self.upsilon.shape = (self.q, self.d) | |
for h in range(0, self.q): | |
for i in range(0, self.d): | |
e_h = return_e_h(vecLbR[h], self.omega[:, h], vecLyR, vecLhatLyRR) | |
x_i = vecLxR[i] | |
deltaMupsilon_LihR = return_deltaMupsilon_LihR(eta, e_h, x_i) | |
self.upsilon[h][i] += deltaMupsilon_LihR | |
def updateOnDataFaster(self, vecLxR, vecLyR, eta): | |
(vecLbR, vecLhatLyRR) = self.predictFaster(vecLxR) | |
for j in range(0, self.l): | |
g_j = return_g_j(vecLyR[j], vecLhatLyRR[j]) | |
self.theta[j] -= eta * g_j | |
self.omega[j] += eta * g_j * vecLbR | |
for h in range(0, self.q): | |
vecLgR = vecLhatLyRR * (1 - vecLhatLyRR) * (vecLyR - vecLhatLyRR) | |
e_h = vecLbR[h] * (1 - vecLbR[h]) * np.dot(self.omega[:, h], vecLgR) | |
self.Upsilon[h] -= eta * e_h | |
self.upsilon[h] += eta * e_h * vecLxR | |
minusVec = vecLyR - vecLhatLyRR | |
return np.dot(minusVec, minusVec) | |
def updateOnDataEvenFaster(self, vecLxR, vecLyR, eta): | |
(vecLbR, vecLhatLyRR) = self.predictFaster(vecLxR) | |
vecLgR = vecLhatLyRR * (1 - vecLhatLyRR) * (vecLyR - vecLhatLyRR) | |
self.theta -= eta * vecLgR | |
self.omega += eta * vecLgR.reshape((-1, 1)) * vecLbR | |
e = vecLbR * (1 - vecLbR) * np.array(np.mat(vecLgR.reshape((1, -1))) * np.mat(self.omega)).flatten() | |
self.Upsilon -= eta * e | |
self.upsilon += eta * e.reshape((-1, 1)) * vecLxR | |
minusVec = vecLyR - vecLhatLyRR | |
return np.dot(minusVec, minusVec) | |
# 对所有数据做一次更新 | |
def updateOnDatum(self, mulLxR, mulLyR, eta): | |
error = 0.0 | |
for k in range(0, mulLxR.shape[0]): | |
error += self.updateOnDataEvenFaster(mulLxR[k], mulLyR[k], eta) | |
return error / 2 | |
# 对所有数据做count次更新,算法停止的条件比较简单 | |
def updates(self, mulLxR, mulLyR, eta, count): | |
for i in range(0, count): | |
error = self.updateOnDatum(mulLxR, mulLyR, eta) | |
print(error) | |
# 算法停止条件的改进,以及步长的自动调整 | |
def updatesSmarter(self, mulLxR, mulLyR, eta, maxCount): | |
i = 1 | |
stepRate = 1 | |
errorLast = self.updateOnDatum(mulLxR, mulLyR, eta * stepRate) | |
while True: | |
i += 1 | |
errorNow = self.updateOnDatum(mulLxR, mulLyR, eta * stepRate) | |
rate = (errorLast - errorNow) / errorLast | |
if rate > 0.015: | |
stepRate = np.log(rate / 0.015) | |
elif rate > 0.009: | |
stepRate = 1 / np.log(rate / 0.009) | |
else: | |
break; | |
# print(stepRate) | |
# print(errorNow) | |
if i >= maxCount: | |
break; | |
errorLast = errorNow | |
network = Network(400, 100, 10) | |
network.updatesSmarter(train_data, num2class(train_targets), 0.007, 60) | |
predicts = network.predicts(test_data) | |
predicts = class2num(predicts) | |
predicts = predicts.astype(np.int) | |
test_targets = test_targets.astype(int) | |
np.savetxt("test_predictions_library.csv", predicts, fmt='%d', delimiter="\n") | |
print(sum(test_targets==predicts) * 1.0 /predicts.shape[0]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM python:3.5 | |
ADD sources.list /etc/apt/sources.list | |
RUN apt-get update | |
RUN pip install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple | |
RUN pip install keras -i https://pypi.tuna.tsinghua.edu.cn/simple | |
RUN apt-get install -y curl git | |
RUN apt-get install -y vim | |
RUN mkdir -p ~/.vim/autoload ~/.vim/bundle && curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim | |
RUN mkdir -p ~/.vim/bundle && cd ~/.vim/bundle && git clone https://github.com/klen/python-mode.git | |
ADD vimrc ~/.vimrc | |
RUN apt-get install --assume-yes zsh | |
# RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM continuumio/anaconda:latest | |
ADD sources.list /etc/apt/sources.list | |
RUN apt-get update | |
RUN apt-get install --assume-yes git curl | |
RUN apt-get install --assume-yes vim | |
RUN git clone https://github.com/amix/vimrc.git ~/.vim_runtime | |
RUN sh ~/.vim_runtime/install_awesome_vimrc.sh | |
RUN apt-get install --assume-yes zsh | |
# RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
deb http://mirrors.163.com/debian/ jessie main non-free contrib | |
deb http://mirrors.163.com/debian/ jessie-updates main non-free contrib | |
deb http://mirrors.163.com/debian/ jessie-backports main non-free contrib | |
deb-src http://mirrors.163.com/debian/ jessie main non-free contrib | |
deb-src http://mirrors.163.com/debian/ jessie-updates main non-free contrib | |
deb-src http://mirrors.163.com/debian/ jessie-backports main non-free contrib | |
deb http://mirrors.163.com/debian-security/ jessie/updates main non-free contrib | |
deb-src http://mirrors.163.com/debian-security/ jessie/updates main non-free contrib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Pathogen load | |
filetype off | |
call pathogen#infect() | |
call pathogen#helptags() | |
filetype plugin indent on | |
syntax on |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
machine learning homework environment