Merge pull request #209 from apachecn/dev

定期合并 - Dev
This commit is contained in:
片刻 2018-05-18 16:22:00 +08:00 committed by GitHub
commit 352280f95e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 241 additions and 106 deletions

View File

@ -0,0 +1,196 @@
# Dogs vs. Cats (kaggle 猫狗大战)
Create an algorithm to distinguish dogs from cats.
正如上面这句话所说,我们的目的就是创建一个算法,来对混合猫狗图片的数据集中,将猫和狗分别识别出来。
## 一、简介
猫狗大战这个项目其实与我们之前做的数字识别类似,只不过是图片复杂了一些。当然,我们这次使用深度学习,来完成我们想要做的事情。
## 二、安装包/第三方库要求
- Python 3.x
- Pytorch
## 三、数据预处理
### 1、本次的数据来自 kaggle 的比赛项目 [dogs-vs-cats](https://www.kaggle.com/c/dogs-vs-cats)
### 2、查看数据格式
- 训练数据
![trainDataset](../../../static/images/competitions/playground/train.png)
- 训练数据集 - 说明:训练数据集中的数据,是经过人工标记的数据,类别和数字之间使用的 "." (点)做的分隔。
- 测试数据
![testDataset](../../../static/images/competitions/playground/test.png)
- 测试数据集 - 说明:测试数据集中的数据,是没有经过人工标记的数据,没有对应的类别,只有一些相应的数字号码。
### 3、对数据的预处理
#### 3.1、提取训练 & 测试数据集的编号
训练数据集 & 测试数据集 给出的序号和 label 都是在文件名称中。
```python
imgs = [os.path.join(root, img) for img in os.listdir(root)]
# test1即测试数据集 D:/dataset/dogs-vs-cats/test1
# train: 即训练数据集D:/dataset/dogs-vs-cats/train
if self.test:
# 提取 测试数据集的序号,
# 如 x = 'd:/path/123.jpg'
# x.split('.') 得到 ['d:/path/123', 'jpg']
# x.split('.')[-2] 得到 d:/path/123
# x.split('.')[-2].split('/') 得到 ['d:', 'path', '123']
# x.split('.')[-2].split('/')[-1] 得到 123
imgs = sorted(imgs, key=lambda x: int(x.split('.')[-2].split('/')[-1]))
else:
# 如果不是测试集的话就是训练集我们只切分一下仍然得到序号123
imgs = sorted(imgs, key=lambda x: int(x.split('.')[-2]))
```
#### 3.2、划分训练集 & 验证集
首先我们知道我们手里的数据现在只有训练集和测试集,并没有验证集。那么为了我们训练得到的模型更好地拟合我们的测试数据,我们人为地将训练数据划分为 训练数据 + 验证数据(比例设置为 7:3
```python
# 获取图片的数量
imgs_num = len(imgs)
# 划分训练、验证集,验证集:训练集 = 3:7
# 判断是否为测试集
if self.test:
# 如果是 测试集,那么 就直接赋值
self.imgs = imgs
# 判断是否为 训练集
elif train:
# 如果是训练集,那么就把数据集的开始位置的数据 到 70% 部分的数据作为训练集
self.imgs = imgs[:int(0.7 * imgs_num)]
else:
# 这种情况就是划分验证集啦,从 70% 部分的数据 到达数据的末尾,全部作为验证集
self.imgs = imgs[int(0.7 * imgs_num):]
```
#### 3.3、测试集,验证集和训练集的数据转换
```python
# 数据的转换操作,测试集,验证集,和训练集的数据转换有所区别
if transforms is None:
# 如果转换操作没有设置,那我们设置一个转换
normalize = T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
# 测试集 和 验证集 的转换
# 判断如果是测试集或者不是训练集(也就是说是验证集),就应用我们下边的转换
if self.test or not train:
self.trainsforms = T.Compose([T.Resize(224), T.CenterCrop(224), T.ToTensor(), normalize])
else:
# 如果是测试集的话,使用另外的转换
self.transforms = T.Compose([T.Resize(256), T.RandomResizedCrop(224), T.RandomHorizontalFlip(), T.ToTensor(), normalize])
```
#### 3.4、重写子类 / 函数
这里我们使用了 torch.utils.data 中的一些函数,比如 Dataset
class torch.utils.data.Dataset 表示 Dataset 的抽象类,所有其他的数据集都应继承该类。所有子类都应该重写 __len__ ,提供数据集大小的方法,和 __getitem__ ,支持从 0 到 len(self) 整数索引的方法。
```python
def __len__(self):
return len(self.imgs)
def __getitem__(self, index):
img_path = self.imgs[index]
# 判断,如果是测试集的数据的话,那就返回对应的序号,比如 d:path/123.jpg 返回 123
if self.test:
label = int(self.imgs[index].split('.')[-2].split('/')[-1])
else:
# 如果不是测试集的数据那么会有相应的类别label也就是对应的dog 和 catdog 为 1cat 为0
label = 1 if 'dog' in img_path.split('/')[-1] else 0
# 这里使用 Pillow 模块,使用 Image 打开一个图片
data = Image.open(img_path)
# 使用我们定义的 transforms 将图片转换详情参考https://pytorch.org/docs/stable/torchvision/transforms.html#transforms-on-pil-image
# 默认的 transforms 设置的是 none
data = self.transforms(data)
# 将转换完成的 data 以及对应的 label如果有的话返回
return data,label
```
#### 3.5、数据加载
```python
# 训练数据集的路径
train_path = 'D:/dataset/dogs-vs-cats/train'
# 从训练数据集的存储路径中提取训练数据集
train_dataset = GetData(train_path, train=True)
# 将训练数据转换成 mini-batch 形式
load_train = data.DataLoader(train_dataset, batch_size=20, shuffle=True, num_workers=1)
# 测试数据的获取
# 首先设置测试数据的路径
test_path = 'D:/dataset/dogs-vs-cats/test1'
# 从测试数据集的存储路径中提取测试数据集
test_path = GetData(test_path, test=True)
# 将测试数据转换成 mini-batch 形式
loader_test = data.DataLoader(test_dataset, batch_size=3, shuffle=True, num_workers=1)
```
## 四、构建 CNN 模型
```python
# 调用我们现成的 AlexNet() 模型
cnn = AlexNet()
# 将模型打印出来观察一下
print(cnn)
```
## 五、设置相应的优化器和损失函数
我们已经构造完成了 CNN 模型,并将我们所需要的数据进行了相应的预处理。那我们接下来的一步就是定义相应的损失函数和优化函数。
torch.optim 是一个实现各种优化算法的软件包。
```python
# 设置优化器和损失函数
# 这里我们使用 Adam 优化器,使用的损失函数是 交叉熵损失
optimizer = torch.optim.Adam(cnn.parameters(), lr=0.005, betas=(0.9, 0.99)) # 优化所有的 cnn 参数
loss_func = nn.CrossEntropyLoss() # 目标 label 不是 one-hotted 类型的
```
## 六、训练模型
数据以及相对应的损失函数和优化器,我们都已经设置好了,那接下来就是紧张刺激的训练模型环节了。
```python
# 训练模型
# 设置训练模型的次数,这里我们设置的是 10 次,也就是用我们的训练数据集对我们的模型训练 10 次,为了节省时间,我们可以只训练 1 次
EPOCH = 10
# 训练和测试
for epoch in range(EPOCH):
num = 0
# 给出 batch 数据,在迭代 train_loader 的时候对 x 进行 normalize
for step, (x, y) in enumerate(loader_train):
b_x = Variable(x) # batch x
b_y = Variable(y) # batch y
output = cnn(b_x) # cnn 的输出
loss = loss_func(output, b_y) # 交叉熵损失
optimizer.zero_grad() # 在这一步的训练步骤上,进行梯度清零
loss.backward() # 反向传播,并进行计算梯度
optimizer.step() # 应用梯度
# 可以打印一下
# print('-'*30, step)
if step % 20 == 0:
num += 1
for _, (x_t, y_test) in enumerate(loader_test):
x_test = Variable(x_t) # batch x
test_output = cnn(x_test)
pred_y = torch.max(test_output, 1)[1].data.squeeze()
accuracy = sum(pred_y == y_test) / float(y_test.size(0))
print('Epoch: ', epoch, '| Num: ', num, '| Step: ', step, '| train loss: %.4f' % loss.data[0], '| test accuracy: %.4f' % accuracy)
```

View File

@ -4,7 +4,7 @@
* git 是一个版本控制工具.
* Github 是一个基于 git 的社会化代码分享社区, 所谓 social coding.
* 开源项目是可以免费托管到 GitHub 上面, 在 GitHub 上你基本上可以找到任何你想要的代码.
*开源项目是可以免费托管到GitHub上面在GitHub上你基本上可以找到任何你想要的代码。
## 基本用途
@ -18,9 +18,9 @@
## 下载地址
### 1.客户端安装(三种方式都可行)
### 1.客户端安装(例如Mac 三种方式都可行)
> (一 客户端操作: https://desktop.github.com/
> (一 客户端操作: https://desktop.github.com/ 【不推荐,程序员建议命令行】
> (二 通过 homebrew 安装 git
@ -109,6 +109,10 @@ jiangzl@jiangzhongliandeMacBook-Pro:~$
<img src="../../static/images/docs/GitHub/ApacheCN-GitHub入门操作-Fork到PullRequests.png">
</a>
全局概况图(看不懂就多看几遍)
![](/static/images/docs/GitHub/github_origin_online_remote.jpg)
> 一) fork apachecn/kaggle 项目
![](/static/images/docs/GitHub/github-step-1-fork.jpg)

View File

@ -1,86 +0,0 @@
# [Kaggle](https://www.kaggle.com) 入门操作指南
## [注册](https://www.kaggle.com/?login=true)
1. 首先注册账号
2. 关联 GitHub 账号
![](../static/images/docs/login.jpg)
## [竞赛 - competitions](https://www.kaggle.com/competitions)
* [选择 - All 和 Getting Started](https://www.kaggle.com/competitions?sortBy=deadline&group=all&page=1&pageSize=20&segment=gettingStarted)
![](..//static/images/docs/All-GettingStarted.jpg)
* [选择 - Digit Recognizer数字识别器](https://www.kaggle.com/c/digit-recognizer)
![](../static/images/docs/choose-digit-recognizer.jpg)
* [阅读资料 - Digit Recognizer数字识别器](https://www.kaggle.com/c/digit-recognizer)
**选择 版本框架 和 star 最高的 Kernels 编辑就行,然后模仿 [**数字识别**](/competitions/getting-started/digit-recognizer) 案例更新**
![](/static/images/docs/read-digit-recognizer.jpg)
## 项目规范(以DigitRecognizer 为例)
> 文档:结尾文件名为项目名.md
* 案例:`competitions/getting-started/digit-recognizer.md`
* 例如:数字识别,文档是属于 `competitions -> GettingStarted` 下面,所以创建 `competitions/getting-started` 存放文档就行
> 图片:结尾文件名可自由定义
* 案例:`static/images/comprtitions/getting-started/digit-recognizer/front_page.png`
* 例如:数字识别,图片是属于 `competitions -> GettingStarted -> DigitRecognizer` 下面,所以创建 `competitions/getting-started/digit-recognizer` 存放文档的图片就行
> 代码:结尾文件名可自由定义.py
* 案例:`src/python/getting-started/digit-recognizer/dr_knn_pandas.py`
* 例如:数字识别,代码只有 `竞赛` 有,所以直接创建 `getting-started/digit-recognizer` 存放代码就行
* 要求(方法:完全解耦)
1. 加载数据
2. 预处理数据(可没)
3. 训练模型
4. 评估模型(可没)
5. 导出数据
* 标注python和编码格式
```python
#!/usr/bin/python
# coding: utf-8
```
* 标注项目的描述
```python
'''
Created on 2017-10-26
Update on 2017-10-26
Author: 【如果是个人】片刻
Team: 【如果是团队】装逼从不退缩(张三、李四 等等)
Github: https://github.com/apachecn/kaggle
'''
```
> 数据:结尾文件名可自由定义
* 输入:`datasets/getting-started/digit-recognizer/input/train.csv`
* 输出:`datasets/getting-started/digit-recognizer/ouput/Result_sklearn_knn.csv`
* 例如:数字识别,数据只有 `竞赛` 有,所以直接创建 `getting-started/digit-recognizer` 存放数据就行
> 结果提交
将数据的输出结果提交到项目的页面中
<a href="https://www.kaggle.com/c/digit-recognizer/submit" target="_blank">
<img src="../static/images/docs/kaggle-submit.jpg">
</a>
## docs目录可忽略
`docs 目录存放的是 ApacheCN 整理的操作or说明文档和 kaggle 网站内容没有关系`
**后面会持续更新**

View File

@ -14,15 +14,15 @@ import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
import sys
data_dir = '/opt/data/kaggle/getting-started/digit-recognizer/'
data_dir = '/Users/wuyanxue/Documents/GitHub/datasets/getting-started/digit-recognizer/'
# 加载数据
def opencsv():
# 使用 pandas 打开
data = pd.read_csv(os.path.join(data_dir, 'train.csv'))
data1 = pd.read_csv(os.path.join(data_dir, 'test.csv'))
data = pd.read_csv(os.path.join(data_dir, 'input/train.csv'))
data1 = pd.read_csv(os.path.join(data_dir, 'input/test.csv'))
train_data = data.values[0:, 1:] # 读入全部训练数据, [行,列]
train_label = data.values[0:, 0] # 读取列表的第一列
@ -95,9 +95,9 @@ def dRecognition_knn():
# 结果预测
testLabel = knnClf.predict(testData)
# 结果的输出
saveResult(testLabel, os.path.join(data_dir, 'Result_sklearn_knn.csv'))
saveResult(testLabel, os.path.join(data_dir, 'output/Result_sklearn_knn.csv'))
print("finish!")
stop_time_r = time.time()
print('classify time used:%f' % (stop_time_r - start_time))

View File

@ -9,22 +9,26 @@ Github: https://github.com/apachecn/kaggle
PCA主成成分分析
'''
import os.path
import csv
import time
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
# 数据路径
data_dir = '/Users/wuyanxue/Documents/GitHub/datasets/getting-started/digit-recognizer/'
# 加载数据
def opencsv():
print('Load Data...')
# 使用 pandas 打开
dataTrain = pd.read_csv('datasets/getting-started/digit-recognizer/input/train.csv')
dataPre = pd.read_csv('datasets/getting-started/digit-recognizer/input/test.csv')
dataTrain = pd.read_csv(os.path.join(data_dir, 'input/train.csv'))
dataPre = pd.read_csv(os.path.join(data_dir, 'input/test.csv'))
trainData = dataTrain.values[:, 1:] # 读入全部训练数据
trainLabel = dataTrain.values[:, 0]
preData = dataPre.values[:, :] # 测试全部测试个数据
@ -57,6 +61,7 @@ def dRCsv(x_train, x_test, preData, COMPONENT_NUM):
return pcaTrainData, pcaTestData, pcaPreData
# 训练模型
def trainModel(trainData, trainLabel):
print('Train SVM...')
@ -179,7 +184,6 @@ def getModel(filename):
fr = open(filename, 'rb')
return pickle.load(fr)
def trainDRSVM():
startTime = time.time()
@ -188,8 +192,8 @@ def trainDRSVM():
# 模型训练 (数据预处理-降维)
optimalSVMClf, pcaPreData = getOptimalAccuracy(trainData, trainLabel, preData)
storeModel(optimalSVMClf, 'datasets/getting-started/digit-recognizer/ouput/Result_sklearn_SVM.model')
storeModel(pcaPreData, 'datasets/getting-started/digit-recognizer/ouput/Result_sklearn_SVM.pcaPreData')
storeModel(optimalSVMClf, os.path.join(data_dir, 'output/Result_sklearn_SVM.model'))
storeModel(pcaPreData, os.path.join(data_dir, 'output/Result_sklearn_SVM.pcaPreData'))
print("finish!")
stopTime = time.time()
@ -199,25 +203,42 @@ def trainDRSVM():
def preDRSVM():
startTime = time.time()
# 加载模型和数据
optimalSVMClf = getModel('datasets/getting-started/digit-recognizer/ouput/Result_sklearn_SVM.model')
pcaPreData = getModel('datasets/getting-started/digit-recognizer/ouput/Result_sklearn_SVM.pcaPreData')
optimalSVMClf = getModel(os.path.join(data_dir, 'output/Result_sklearn_SVM.model'))
pcaPreData = getModel(os.path.join(data_dir, 'output/Result_sklearn_SVM.pcaPreData'))
# 结果预测
testLabel = optimalSVMClf.predict(pcaPreData)
# print("testLabel = %f" % testscore)
# 结果的输出
saveResult(testLabel, 'datasets/getting-started/digit-recognizer/ouput/Result_sklearn_SVM.csv')
saveResult(testLabel, os.path.join(data_dir, 'output/Result_sklearn_SVM.csv'))
print("finish!")
stopTime = time.time()
print('PreModel load time used:%f s' % (stopTime - startTime))
# 数据可视化
def dataVisulization(data, labels):
pca = PCA(n_components=2, whiten=True) # 使用PCA方法降到2维
pca.fit(data)
pcaData = pca.transform(data)
uniqueClasses = set(labels)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
for cClass in uniqueClasses:
plt.scatter(pcaData[labels==cClass, 0], pcaData[labels==cClass, 1])
plt.xlabel('$x_1$')
plt.ylabel('$x_2$')
plt.title('MNIST visualization')
plt.show()
if __name__ == '__main__':
trainData, trainLabel, preData = opencsv()
dataVisulization(trainData, trainLabel)
# 训练并保存模型
trainDRSVM()
#trainDRSVM()
# 分析数据
analyse_data(trainData)
#analyse_data(trainData)
# 加载预测数据集
# preDRSVM()
#preDRSVM()

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB