<jupyter_start><jupyter_text>Titanic  导入本次需要的包<jupyter_code>import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.utils.data as Data
import urllib.request
from sklearn import preprocessing
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
from torchsummary import summary
from matplotlib.font_manager import FontProperties

torch.__version__<jupyter_output><empty_output><jupyter_text>数据预处理 具体的数据处理方式可以参见[Tensorflow 笔记 Ⅵ——Titanic Keras建模与应用](https://blog.csdn.net/qq_39567427/article/details/105843934)，里面有详细的梳理，这里就不在赘述<jupyter_code>def prepare_data(df_data):
    # 去掉name列，name对于数据特征没有贡献
    df = df_data.drop(['name'], axis=1)
    # 获取age列均值用于补充age列的空值
    age_mean = df['age'].mean()
    df['age'] = df['age'].fillna(age_mean)
    # 获取fare列均值用于补充fare列的空值
    fare_mean = df['fare'].mean()
    df['fare'] = df['fare'].fillna(fare_mean)
    # 性别映射关系，将female映射为0，male映射为1
    df['sex'] = df['sex'].map({'female':0, 'male':1}).astype(int)
    # 将embarked列空值填充为S
    df['embarked'] = df['embarked'].fillna('S')
    # 再将embarked列所有英文字母映射为数字，按照C:0，Q:1，S:2的标准
    df['embarked'] = df['embarked'].map({'C':0, 'Q':1, 'S':2}).astype(int)

    # 将数据转换为数组
    ndarray_data = df.values

    features = ndarray_data[:, 1:]
    label = ndarray_data[:, 0]

    minmax_scale = preprocessing.MinMaxScaler(feature_range=(0, 1))
    norm_features = minmax_scale.fit_transform(features)

    return norm_features, label<jupyter_output><empty_output><jupyter_text>读取`.xls`文件需要安装`xlrd`模块<jupyter_code>dataframe = pd.read_excel('./titanic/titanic3.xls')

# 选择特征贡献的列
selected_cols= ['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked']
# 生成副本，以免出现警告
selected_dataframe = dataframe[selected_cols].copy()
# 随机打乱，frac=1表示100％打乱
selected_dataframe = selected_dataframe.sample(frac=1)

x_data, y_data = prepare_data(selected_dataframe)

# 划分训练集及验证集，比例为8：2（4：1）
train_size = int(len(x_data) * 0.8)

x_train = x_data[:train_size]
y_train = y_data[:train_size]

x_test = x_data[train_size:]
y_test = y_data[train_size:]<jupyter_output><empty_output><jupyter_text>数据集生成<jupyter_code>BATCH_SIZE = 50

train_dataset = Data.TensorDataset(torch.from_numpy(x_train).type(torch.FloatTensor), torch.from_numpy(y_train).type(torch.LongTensor))
train_loader = Data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)

test_dataset = Data.TensorDataset(torch.from_numpy(x_test).type(torch.FloatTensor), torch.from_numpy(y_test).type(torch.LongTensor))
test_loader = Data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE * 5, shuffle=True)<jupyter_output><empty_output><jupyter_text>获取设备信息<jupyter_code>device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

print(device)<jupyter_output>cuda:0<jupyter_text>开始训练 模型构建DNN<jupyter_code>class DNN(nn.Module):
    def __init__(self, inputdim):
        super(DNN, self).__init__()
        self.dnn = nn.Sequential(
            nn.Linear(inputdim, 32),
            nn.Dropout(0.3),
            nn.ReLU(),
            nn.Linear(32, 16),
            nn.Dropout(0.2),
            nn.Sigmoid(),
            nn.Linear(16, 2),
            nn.Dropout(0.1),
            nn.Sigmoid()
        )

    def forward(self, inputs):
        return self.dnn(inputs)
dnn = DNN(inputdim=7).to(device)

summary(dnn, input_size=(7,))<jupyter_output>----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Linear-1                   [-1, 32]             256
           Dropout-2                   [-1, 32]               0
              ReLU-3                   [-1, 32]               0
            Linear-4                   [-1, 16]             528
           Dropout-5                   [-1, 16]               0
           Sigmoid-6                   [-1, 16]               0
            Linear-7                    [-1, 2]              34
           Dropout-8                    [-1, 2]               0
           Sigmoid-9                    [-1, 2]               0
================================================================
Total params: 818
Trainable params: 818
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backwa[...]<jupyter_text>超参数设置<jupyter_code>EPOCHS = 500
LR = 0.001<jupyter_output><empty_output><jupyter_text>权重重置函数<jupyter_code>def weight_reset(m):
    if isinstance(m, torch.nn.Conv2d) or isinstance(m, torch.nn.Linear):
        m.reset_parameters()<jupyter_output><empty_output><jupyter_text>定义优化器与损失函数<jupyter_code>optimizer = torch.optim.Adam(dnn.parameters(), lr=LR)
loss_func = nn.CrossEntropyLoss()<jupyter_output><empty_output><jupyter_text>开始训练<jupyter_code>%%time

# 权重初始化
dnn.apply(weight_reset)
# 生成迭代器
dataiter = iter(test_loader)

train_acc_list = []
test_acc_list = []
train_loss_list = []
test_loss_list = []

for epoch in range(EPOCHS):
    train_step_acc = []
    train_step_loss = []
    test_step_loss = []
    test_step_acc = []
    for step, data in enumerate(train_loader):
        # 数据提取并转为GPU形式
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)
        # 结果预测并获取预测值
        outputs = dnn(inputs)
        train_pred_y = torch.max(outputs, 1)[1].data.squeeze()
        # 获取准确率
        train_acc = (train_pred_y == labels).sum().item() / float(labels.size(0))
        # 获取损失值
        loss = loss_func(outputs, labels)
        train_step_loss.append(float(loss))
        train_step_acc.append(train_acc)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        try:
            test_inputs, test_labels = next(dataiter)
        except StopIteration:
            dataiter = iter(test_loader)
            test_inputs, test_labels = next(dataiter)
        
        # 数据提取并转为GPU形式
        test_inputs, test_labels = test_inputs.to(device), test_labels.to(device)
        # 结果预测并获取预测值
        test_outputs = dnn(test_inputs)
        test_pred_y = torch.max(test_outputs, 1)[1].data.squeeze()
        # 获取准确率
        test_acc = (test_pred_y == test_labels).sum().item() / float(test_labels.size(0))
        test_step_acc.append(test_acc)
        # 获取损失值
        test_loss = loss_func(test_outputs, test_labels)
        test_step_loss.append(float(test_loss))
        test_step_acc.append(test_acc)
        
    train_acc_list.append(np.mean(train_step_acc))
    train_loss_list.append(np.mean(train_step_loss))
    test_acc_list.append(np.mean(test_step_acc))
    test_loss_list.append(np.mean(test_step_loss))
    
    print(('EPOCH={:3d}/{:3d}, train_loss={:.4f}, '
           'train_acc={:.4f}, valid_loss={:.4f}, val_acc={:.4f}').format(epoch + 1,
                                                                EPOCHS,
                                                                np.mean(train_step_loss),
                                                                np.mean(train_step_acc),
                                                                np.mean(test_step_loss),
                                                                np.mean(test_step_acc)))<jupyter_output>EPOCH=  1/500, train_loss=0.6845, train_acc=0.5990, valid_loss=0.6830, val_acc=0.6179
EPOCH=  2/500, train_loss=0.6762, train_acc=0.6104, valid_loss=0.6702, val_acc=0.6510
EPOCH=  3/500, train_loss=0.6751, train_acc=0.5882, valid_loss=0.6728, val_acc=0.6110
EPOCH=  4/500, train_loss=0.6694, train_acc=0.6159, valid_loss=0.6632, val_acc=0.6291
EPOCH=  5/500, train_loss=0.6631, train_acc=0.6124, valid_loss=0.6702, val_acc=0.5873
EPOCH=  6/500, train_loss=0.6609, train_acc=0.6169, valid_loss=0.6608, val_acc=0.6122
EPOCH=  7/500, train_loss=0.6567, train_acc=0.6150, valid_loss=0.6560, val_acc=0.6171
EPOCH=  8/500, train_loss=0.6548, train_acc=0.6114, valid_loss=0.6493, val_acc=0.6116
EPOCH=  9/500, train_loss=0.6529, train_acc=0.6075, valid_loss=0.6419, val_acc=0.6183
EPOCH= 10/500, train_loss=0.6429, train_acc=0.6174, valid_loss=0.6327, val_acc=0.6337
EPOCH= 11/500, train_loss=0.6326, train_acc=0.6227, valid_loss=0.6228, val_acc=0.6381
EPOCH= 12/500, train_loss=0.6275, train_acc=0.6189, va[...]<jupyter_text>训练效果可视化<jupyter_code>fig = plt.gcf()
fig.set_size_inches(10, 5)
ax1 = fig.add_subplot(111)
ax1.set_title('Train and Validation Picture')
ax1.set_ylabel('Loss value')
line1, = ax1.plot(train_loss_list, color=(0.5, 0.5, 1.0), label='Loss train')
line2, = ax1.plot(test_loss_list, color=(0.5, 1.0, 0.5), label='Loss valid')
ax2 = ax1.twinx()
ax2.set_ylabel('Accuracy value')
line3, = ax2.plot(train_acc_list, color=(0.5, 0.5, 0.5), label='Accuracy train')
line4, = ax2.plot(test_acc_list, color=(1, 0, 0), label='Accuracy valid')
plt.legend(handles=(line1, line2, line3, line4), loc='best')
plt.show()<jupyter_output><empty_output><jupyter_text>类别验证<jupyter_code>test_loader = Data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE * 5, shuffle=True)

# 创建一个10维列表，存储后面每个类累计的值
class_correct = list(0. for i in range(2))
class_total = list(0. for i in range(2))
with torch.no_grad():
    for data in test_loader:
        inputs, labels = data
        inputs, labels = inputs.view([-1, 7]).to(device), labels.to(device)
        # 独热码类型分布，输出为4x10的矩阵，分别表示batchsize：4以及类别：10
        outputs = dnn(inputs)
        predicted = torch.max(outputs, 1)[1]
        
        # 将输入张量形状中的 1 去除并返回，例如[1, 2, 3]
        # 返回[2, 3]，当给定 dim 时，那么挤压操作只在给定维度
        # 在这里由于返回的bool值，可以不使用.squeeze()操作
        c = (predicted == labels).squeeze()
        # 循环遍历每一个批次
        for i in range(labels.size()[0]):
            label = labels[i]
            # 获取具体值
            class_correct[label] += c[i].item()
            # 对应类别自加
            class_total[label] += 1

for i in range(2):
    print('Accuracy of %s : %2d %%' % (
        i, 100 * class_correct[i] / class_total[i]))<jupyter_output>Accuracy of 0 : 92 %
Accuracy of 1 : 69 %<jupyter_text>Jack & Rose<jupyter_code>'''
Jack_info = [0, 'Jack', 3, 'male', 23, 1, 0, 5.0000, 'S']=[3, 1, 23, 1, 0, 5.0000, 2]
Rose_info = [1, 'Rose', 1, 'female', 20, 1, 0, 100.0000, 'S']=[1, 0, 20, 1, 0, 100.0000, 2]
'''
# 按照数据集进行同样的归一化
minmax_scale = preprocessing.MinMaxScaler(feature_range=(0, 1))
couple = minmax_scale.fit_transform(np.array([[3, 1, 23, 1, 0, 5.0000, 2], [1, 0, 20, 1, 0, 100.0000, 2]]))

couple = torch.from_numpy(couple).type(torch.FloatTensor).to(device)
outputs = dnn(couple)
predicted = torch.max(outputs, 1)[1]


print('Rose survived probability: %.5f'% outputs[0][predicted[0]].item(),
      '\nRose is survival',
      '\nJack survived probability: %.5f'%outputs[1][predicted[0]].item(),
      '\nJack is not survival')<jupyter_output>Rose survived probability: 0.99981 
Rose is survival 
Jack survived probability: 0.00043 
Jack is not survival<jupyter_text>Breast Cancer  数据读取与展示 导入数据读取模块，读取数据<jupyter_code>from sklearn.datasets import load_breast_cancer

breast_cancer = load_breast_cancer()<jupyter_output><empty_output><jupyter_text>查看数据特征以及标签的维度<jupyter_code>print('data features shape:', breast_cancer['data'].shape,
      '\ndata labels shape  :', breast_cancer['target'].shape)<jupyter_output>data features shape: (569, 30) 
data labels shape  : (569,)<jupyter_text>查看特征名<jupyter_code>for name in breast_cancer['feature_names']:
    print(name, end=' ')
print('\n\n特征数量: ', len(breast_cancer['feature_names']))<jupyter_output>mean radius mean texture mean perimeter mean area mean smoothness mean compactness mean concavity mean concave points mean symmetry mean fractal dimension radius error texture error perimeter error area error smoothness error compactness error concavity error concave points error symmetry error fractal dimension error worst radius worst texture worst perimeter worst area worst smoothness worst compactness worst concavity worst concave points worst symmetry worst fractal dimension 

特征数量:  30<jupyter_text>查看标签名，其标签的数字映射按照`target_names`排列顺序<jupyter_code>for name in breast_cancer.target_names:
    print(name, list(breast_cancer.target_names).index(name), end=', ')
print('\n\n标签类别: ', len(breast_cancer.target_names))<jupyter_output>malignant 0, benign 1, 

标签类别:  2<jupyter_text>获取部分数据的标签以及训练数据<jupyter_code>breast_cancer['data'][0]
breast_cancer.target[[1, 11, 111]]<jupyter_output><empty_output><jupyter_text>**注意：`sklearn`的数据集可以在sklearn安装包下查看得到，比如我的可以在`E:\Anaconda3\envs\pytorch1.6.0\Lib\site-packages\sklearn\datasets\data\breast_cancer.csv`，这个文件夹包含了`sklearn`所有集成的数据集**  数据归一化<jupyter_code>minmax_scale = preprocessing.MinMaxScaler(feature_range=(0, 1))

train_dataset = Data.TensorDataset(torch.from_numpy(minmax_scale.fit_transform(breast_cancer['data'][:400])).type(torch.FloatTensor), torch.from_numpy(breast_cancer['target'][:400]).type(torch.LongTensor))
train_loader = Data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)

test_dataset = Data.TensorDataset(torch.from_numpy(minmax_scale.fit_transform(breast_cancer['data'][400:])).type(torch.FloatTensor), torch.from_numpy(breast_cancer['target'][400:]).type(torch.LongTensor))
test_loader = Data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE * 5, shuffle=True)<jupyter_output><empty_output><jupyter_text>开始训练 **注意：`Breast Cancer` 中未涉及的超参数，模型构建等均沿用前面部分**<jupyter_code>dnn = DNN(inputdim=30).to(device)

summary(dnn, input_size=(30,))<jupyter_output>----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Linear-1                   [-1, 32]             992
           Dropout-2                   [-1, 32]               0
              ReLU-3                   [-1, 32]               0
            Linear-4                   [-1, 16]             528
           Dropout-5                   [-1, 16]               0
           Sigmoid-6                   [-1, 16]               0
            Linear-7                    [-1, 2]              34
           Dropout-8                    [-1, 2]               0
           Sigmoid-9                    [-1, 2]               0
================================================================
Total params: 1,554
Trainable params: 1,554
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/ba[...]<jupyter_text>定义新的优化器，设置更小的学习率<jupyter_code>optimizer = torch.optim.Adam(dnn.parameters(), lr=0.0001)<jupyter_output><empty_output><jupyter_text>开始训练<jupyter_code>%%time

# 权重初始化
dnn.apply(weight_reset)
# 生成迭代器
dataiter = iter(test_loader)

train_acc_list = []
test_acc_list = []
train_loss_list = []
test_loss_list = []

for epoch in range(EPOCHS):
    train_step_acc = []
    train_step_loss = []
    test_step_loss = []
    test_step_acc = []
    for step, data in enumerate(train_loader):
        # 数据提取并转为GPU形式
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)
        # 结果预测并获取预测值
        outputs = dnn(inputs)
        train_pred_y = torch.max(outputs, 1)[1].data.squeeze()
        # 获取准确率
        train_acc = (train_pred_y == labels).sum().item() / float(labels.size(0))
        # 获取损失值
        loss = loss_func(outputs, labels)
        train_step_loss.append(float(loss))
        train_step_acc.append(train_acc)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        try:
            test_inputs, test_labels = next(dataiter)
        except StopIteration:
            dataiter = iter(test_loader)
            test_inputs, test_labels = next(dataiter)
        
        # 数据提取并转为GPU形式
        test_inputs, test_labels = test_inputs.to(device), test_labels.to(device)
        # 结果预测并获取预测值
        test_outputs = dnn(test_inputs)
        test_pred_y = torch.max(test_outputs, 1)[1].data.squeeze()
        # 获取准确率
        test_acc = (test_pred_y == test_labels).sum().item() / float(test_labels.size(0))
        test_step_acc.append(test_acc)
        # 获取损失值
        test_loss = loss_func(test_outputs, test_labels)
        test_step_loss.append(float(test_loss))
        test_step_acc.append(test_acc)
        
    train_acc_list.append(np.mean(train_step_acc))
    train_loss_list.append(np.mean(train_step_loss))
    test_acc_list.append(np.mean(test_step_acc))
    test_loss_list.append(np.mean(test_step_loss))
    
    print(('EPOCH={:3d}/{:3d}, train_loss={:.4f}, '
           'train_acc={:.4f}, valid_loss={:.4f}, val_acc={:.4f}').format(epoch + 1,
                                                                EPOCHS,
                                                                np.mean(train_step_loss),
                                                                np.mean(train_step_acc),
                                                                np.mean(test_step_loss),
                                                                np.mean(test_step_acc)))<jupyter_output>EPOCH=  1/500, train_loss=0.6885, train_acc=0.5800, valid_loss=0.6824, val_acc=0.7093
EPOCH=  2/500, train_loss=0.6895, train_acc=0.5700, valid_loss=0.6809, val_acc=0.7293
EPOCH=  3/500, train_loss=0.6900, train_acc=0.5575, valid_loss=0.6807, val_acc=0.7152
EPOCH=  4/500, train_loss=0.6886, train_acc=0.5700, valid_loss=0.6797, val_acc=0.7271
EPOCH=  5/500, train_loss=0.6897, train_acc=0.5450, valid_loss=0.6798, val_acc=0.7049
EPOCH=  6/500, train_loss=0.6881, train_acc=0.5625, valid_loss=0.6784, val_acc=0.7249
EPOCH=  7/500, train_loss=0.6903, train_acc=0.5325, valid_loss=0.6780, val_acc=0.7212
EPOCH=  8/500, train_loss=0.6875, train_acc=0.5675, valid_loss=0.6777, val_acc=0.7167
EPOCH=  9/500, train_loss=0.6896, train_acc=0.5275, valid_loss=0.6776, val_acc=0.7101
EPOCH= 10/500, train_loss=0.6872, train_acc=0.5750, valid_loss=0.6765, val_acc=0.7249
EPOCH= 11/500, train_loss=0.6885, train_acc=0.5425, valid_loss=0.6757, val_acc=0.7286
EPOCH= 12/500, train_loss=0.6878, train_acc=0.5525, va[...]<jupyter_text>训练效果可视化<jupyter_code>fig = plt.gcf()
fig.set_size_inches(10, 5)
ax1 = fig.add_subplot(111)
ax1.set_title('Train and Validation Picture')
ax1.set_ylabel('Loss value')
line1, = ax1.plot(train_loss_list, color=(0.5, 0.5, 1.0), label='Loss train')
line2, = ax1.plot(test_loss_list, color=(0.5, 1.0, 0.5), label='Loss valid')
ax2 = ax1.twinx()
ax2.set_ylabel('Accuracy value')
line3, = ax2.plot(train_acc_list, color=(0.5, 0.5, 0.5), label='Accuracy train')
line4, = ax2.plot(test_acc_list, color=(1, 0, 0), label='Accuracy valid')
plt.legend(handles=(line1, line2, line3, line4), loc='best')
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15790037493304768, 'fraction_numerical': 0.056239957150508835, 'mean_word_length': 2.9456889264581574, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 83, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '23', 'dir': 'jupyter-structured-clean-dedup', 'id': '374799', 'license': 'MIT', 'n_tokens_mistral': 7672, 'n_tokens_neox': 7301, 'n_words': 1049, 'path': 'Titanic 及 breast_cancer 分类应用.ipynb', 'repo_name': 'GuoQuanhao/pytorch-basic-tutorial', 'size': '18670'}