├── 18308013-陈家豪-assignment1 ├── code │ ├── Cross-Entropy-Loss.py │ └── Mean-Square-Error-Loss.py └── report.pdf ├── 18308013-陈家豪-assignment2 ├── code │ ├── SVM.py │ └── linear_classify.py └── report.pdf ├── 18308013-陈家豪-assignment3 ├── code │ └── code.py └── report.pdf ├── 18308013-陈家豪-assignment4 ├── code │ └── code.py └── report.pdf ├── 18308013-陈家豪-assignment5 ├── code │ ├── DCGAN_CIFAR10.py │ └── DCGAN_MNIST.py ├── report.pdf └── results │ ├── output.gif │ └── output2.gif ├── Assignment 1.pdf ├── Assignment 2.pdf ├── Assignment 3-期中.pdf ├── Assignment 4.pdf ├── Assignment 5-期末.pdf └── README.md /18308013-陈家豪-assignment1/code/Cross-Entropy-Loss.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | def softmax(matrix, HandleOverflow = True): 4 | if HandleOverflow: 5 | ColMax = matrix.max(axis = 1) 6 | ColMax -= 1 7 | ColMax = np.reshape(ColMax, (ColMax.size, 1)) 8 | temp = np.exp(matrix-ColMax) 9 | else: 10 | temp = np.exp(matrix) 11 | ColSum = temp.sum(axis=1) 12 | ColSum = np.reshape(ColSum, (ColSum.size,1)) 13 | return temp/ColSum 14 | 15 | def train(W, train_X, train_Y, Lambda, learning_rate): 16 | temp = softmax(np.dot(train_X, W)) - train_Y 17 | dW = (1/train_X.shape[0])*np.dot(train_X.T, temp) + 2*Lambda*W 18 | W -= learning_rate*dW 19 | return W 20 | 21 | def predict(W, X): 22 | temp = softmax(np.dot(X, W)) 23 | prediction = temp.argmax(axis=1) 24 | return prediction 25 | 26 | def accuracy(prediction, labels_Y): 27 | current = 0 28 | for i in range(prediction.size): 29 | if labels_Y[i, prediction[i]] == 1: 30 | current += 1 31 | return current/prediction.size 32 | 33 | def CELoss(W, X, Y): 34 | temp = softmax(np.dot(X, W)) 35 | total = 0 36 | return -(1/Y.shape[0])*np.sum(np.log(temp)*Y) 37 | 38 | 39 | def main(): 40 | # 设置超参数 41 | LABEL_NUM = 10 42 | epochs = 100 43 | learning_rate = 0.005 44 | BATCH_SIZE = 512 45 | LAMBDA = 0.01 46 | K = 10 47 | 48 | # 获取训练集数据 49 | train_images = np.load("material/train-images.npy") 50 | train_labels = np.load("material/train-labels.npy") 51 | extend = np.ones(train_images.shape[0]) 52 | train_X = np.c_[extend, train_images] 53 | train_Y = np.zeros((train_labels.size, LABEL_NUM)) 54 | for i in range(train_labels.size): 55 | train_Y[i, train_labels[i]] = 1 56 | # 标准化 57 | meanVal = [] 58 | stdVal = [] 59 | for i in range(train_X.shape[1]): 60 | meanVal.append(np.mean(train_X[:, i])) 61 | stdVal.append(np.std(train_X[:,i])) 62 | if stdVal[i] != 0: 63 | train_X[:, i] = (train_X[:,i]-meanVal[i])/stdVal[i] 64 | 65 | # 获取测试集数据 66 | test_images = np.load("material/test-images.npy") 67 | test_labels = np.load("material/test-labels.npy") 68 | extend = np.ones(test_images.shape[0]) 69 | test_X = np.c_[extend, test_images] 70 | test_Y = np.zeros((test_labels.size, LABEL_NUM)) 71 | for i in range(test_labels.size): 72 | test_Y[i, test_labels[i]] = 1 73 | # 标准化 74 | for i in range(test_X.shape[1]): 75 | if stdVal[i] != 0: 76 | test_X[:, i] = (test_X[:,i]-meanVal[i])/stdVal[i] 77 | 78 | # 设置随机种子,初始化参数 79 | np.random.seed(0) 80 | W = np.random.rand(train_X.shape[1], LABEL_NUM) 81 | 82 | # 训练 83 | train_loss = [] 84 | valid_loss = [] 85 | train_acc = [] 86 | test_acc =[] 87 | for i in range(epochs): 88 | # 打乱训练集数据和标签 89 | state = np.random.get_state() 90 | np.random.shuffle(train_X) 91 | np.random.set_state(state) 92 | np.random.shuffle(train_Y) 93 | # K折交叉验证 94 | block_size = int(train_X.shape[0]/K) 95 | train_loss.append(0) 96 | valid_loss.append(0) 97 | for k in range(K): 98 | # 获取训练集和验证集 99 | ValidBlock_X = train_X[k*block_size:(k+1)*block_size, :] 100 | ValidBlock_Y = train_Y[k*block_size:(k+1)*block_size, :] 101 | TrainBlock_X = np.r_[train_X[:k*block_size, :], train_X[(k+1)*block_size:, :]] 102 | TrainBlock_Y = np.r_[train_Y[:k*block_size, :], train_Y[(k+1)*block_size:, :]] 103 | # mini-batch 104 | for Idx in range(int(TrainBlock_X.shape[0]/BATCH_SIZE)): 105 | # 获取本次更新批次的索引 106 | StartIdx = Idx*BATCH_SIZE 107 | EndIdx = StartIdx+BATCH_SIZE 108 | if EndIdx > TrainBlock_X.shape[0]: 109 | EndIdx = TrainBlock_X.shape[0] 110 | W = train(W, TrainBlock_X[StartIdx:EndIdx,:], TrainBlock_Y[StartIdx:EndIdx,:], LAMBDA, learning_rate) 111 | # 计算损失值 112 | train_loss[-1] += CELoss(W, TrainBlock_X, TrainBlock_Y) 113 | valid_loss[-1] += CELoss(W, ValidBlock_X, ValidBlock_Y) 114 | # 求平均值 115 | train_loss[-1] /= K 116 | valid_loss[-1] /= K 117 | if (i+1)%1 == 0: 118 | train_acc.append(accuracy(predict(W, train_X), train_Y)) 119 | test_acc.append(accuracy(predict(W, test_X), test_Y)) 120 | print("%d/%d:\tAvgTrainLoss = %.6f\tAvgValidLoss = %.6f\tTotalTrainAcc = %.6f\tTotalTestAcc = %.6f"%(i+1, epochs, train_loss[-1], valid_loss[-1], train_acc[-1], test_acc[-1])) 121 | 122 | # 画图 123 | plt.figure() 124 | plt.xlabel("epochs") 125 | plt.ylabel("loss") 126 | plt.xticks(range(0, epochs+1, 10)) 127 | #plt.axes(yscale = "log") 128 | plt.plot(range(epochs), train_loss, c='red', label='train') 129 | plt.plot(range(epochs), valid_loss, c='green', label='valid') 130 | plt.legend() 131 | plt.grid() 132 | plt.savefig('CEloss.jpg', dpi = 1800) 133 | plt.show() 134 | 135 | plt.figure() 136 | plt.xlabel("epochs") 137 | plt.ylabel("acc") 138 | plt.xticks(range(0, epochs+1, 10)) 139 | plt.plot(range(epochs), train_acc, c='red', label='train') 140 | plt.plot(range(epochs), test_acc, c='blue', label='test') 141 | plt.legend() 142 | plt.grid() 143 | plt.savefig('CEacc.jpg', dpi = 1800) 144 | plt.show() 145 | 146 | if __name__=='__main__': 147 | import numpy as np 148 | from matplotlib import pyplot as plt 149 | main() 150 | -------------------------------------------------------------------------------- /18308013-陈家豪-assignment1/code/Mean-Square-Error-Loss.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | def softmax(matrix, HandleOverflow = True): 4 | if HandleOverflow: 5 | ColMax = matrix.max(axis = 1) 6 | ColMax -= 1 7 | ColMax = np.reshape(ColMax, (ColMax.size, 1)) 8 | temp = np.exp(matrix-ColMax) 9 | else: 10 | temp = np.exp(matrix) 11 | ColSum = temp.sum(axis=1) 12 | ColSum = np.reshape(ColSum, (ColSum.size,1)) 13 | return temp/ColSum 14 | 15 | def train(W, train_X, train_Y, Lambda, learning_rate): 16 | sm = softmax(np.dot(train_X, W)) 17 | diag = np.diag(np.dot(train_Y-sm, sm.T)).reshape((-1, 1)) 18 | temp = sm*(sm-train_Y+diag) 19 | dW = (2/train_X.shape[0])*np.dot(train_X.T, temp) + 2*Lambda*W 20 | W -= learning_rate*dW 21 | return W 22 | 23 | def predict(W, X): 24 | temp = softmax(np.dot(X, W)) 25 | prediction = temp.argmax(axis=1) 26 | return prediction 27 | 28 | def accuracy(prediction, labels_Y): 29 | current = 0 30 | for i in range(prediction.size): 31 | if labels_Y[i, prediction[i]] == 1: 32 | current += 1 33 | return current/prediction.size 34 | 35 | def MSELoss(W, X, Y): 36 | temp = softmax(np.dot(X, W)) 37 | return (1/Y.shape[0])*np.sum((Y-temp)**2) 38 | 39 | def main(): 40 | # 超参数设置 41 | LABEL_NUM = 10 42 | epochs = 100 43 | learning_rate = 0.005 44 | BATCH_SIZE = 512 45 | LAMBDA = 0.01 46 | K = 10 47 | 48 | # 获取训练集数据 49 | train_images = np.load("material/train-images.npy") 50 | train_labels = np.load("material/train-labels.npy") 51 | # 添加偏置1 52 | extend = np.ones(train_images.shape[0]) 53 | train_X = np.c_[extend, train_images] 54 | # 将标签转换为one-hot形式 55 | train_Y = np.zeros((train_labels.size, LABEL_NUM)) 56 | for i in range(train_labels.size): 57 | train_Y[i, train_labels[i]] = 1 58 | # 特征标准化 59 | meanVal = [] 60 | stdVal = [] 61 | for i in range(train_X.shape[1]): 62 | meanVal.append(np.mean(train_X[:, i])) 63 | stdVal.append(np.std(train_X[:,i])) 64 | if stdVal[i] != 0: 65 | train_X[:, i] = (train_X[:,i]-meanVal[i])/stdVal[i] 66 | 67 | # 获取测试集数据 68 | test_images = np.load("material/test-images.npy") 69 | test_labels = np.load("material/test-labels.npy") 70 | # 添加偏置1 71 | extend = np.ones(test_images.shape[0]) 72 | test_X = np.c_[extend, test_images] 73 | # 将标签转换为one-hot形式 74 | test_Y = np.zeros((test_labels.size, LABEL_NUM)) 75 | for i in range(test_labels.size): 76 | test_Y[i, test_labels[i]] = 1 77 | # 特征标准化 78 | for i in range(test_X.shape[1]): 79 | if stdVal[i] != 0: 80 | test_X[:, i] = (test_X[:,i]-meanVal[i])/stdVal[i] 81 | 82 | # 设置随机种子,初始化参数 83 | np.random.seed(0) 84 | W = np.random.rand(train_X.shape[1], LABEL_NUM) 85 | 86 | # 训练 87 | train_loss = [] 88 | valid_loss = [] 89 | train_acc = [] 90 | test_acc =[] 91 | for i in range(epochs): 92 | # 打乱训练集数据和标签 93 | state = np.random.get_state() 94 | np.random.shuffle(train_X) 95 | np.random.set_state(state) 96 | np.random.shuffle(train_Y) 97 | # K折交叉验证 98 | block_size = int(train_X.shape[0]/K) 99 | train_loss.append(0) 100 | valid_loss.append(0) 101 | for k in range(K): 102 | ValidBlock_X = train_X[k*block_size:(k+1)*block_size, :] 103 | ValidBlock_Y = train_Y[k*block_size:(k+1)*block_size, :] 104 | TrainBlock_X = np.r_[train_X[:k*block_size, :], train_X[(k+1)*block_size:, :]] 105 | TrainBlock_Y = np.r_[train_Y[:k*block_size, :], train_Y[(k+1)*block_size:, :]] 106 | # mini-batch 107 | for Idx in range(int(TrainBlock_X.shape[0]/BATCH_SIZE)): 108 | # 获取索引 109 | StartIdx = Idx*BATCH_SIZE 110 | EndIdx = StartIdx+BATCH_SIZE 111 | if EndIdx > TrainBlock_X.shape[0]: 112 | EndIdx = TrainBlock_X.shape[0] 113 | W = train(W, TrainBlock_X[StartIdx:EndIdx,:], TrainBlock_Y[StartIdx:EndIdx,:], LAMBDA, learning_rate) 114 | # 计算损失值 115 | train_loss[-1] += MSELoss(W, TrainBlock_X, TrainBlock_Y) 116 | valid_loss[-1] += MSELoss(W, ValidBlock_X, ValidBlock_Y) 117 | train_loss[-1] /= K 118 | valid_loss[-1] /= K 119 | if (i+1)%1 == 0: 120 | train_acc.append(accuracy(predict(W, train_X), train_Y)) 121 | test_acc.append(accuracy(predict(W, test_X), test_Y)) 122 | print("%d/%d:\tAvgTrainLoss = %.6f\tAvgValidLoss = %.6f\tTotalTrainAcc = %.6f\tTotalTestAcc = %.6f"%(i+1, epochs, train_loss[-1], valid_loss[-1], train_acc[-1], test_acc[-1])) 123 | 124 | # 画图 125 | plt.figure() 126 | plt.xlabel("epochs") 127 | plt.ylabel("loss") 128 | plt.xticks(range(0, epochs+1, 10)) 129 | plt.plot(range(epochs), train_loss, c='red', label='train') 130 | plt.plot(range(epochs), valid_loss, c='green', label='valid') 131 | plt.legend() 132 | plt.grid() 133 | plt.savefig('MSEloss.jpg', dpi = 1800) 134 | plt.show() 135 | 136 | plt.figure() 137 | plt.xlabel("epochs") 138 | plt.ylabel("acc") 139 | plt.xticks(range(0, epochs+1, 10)) 140 | plt.plot(range(epochs), train_acc, c='red', label='train') 141 | plt.plot(range(epochs), test_acc, c='blue', label='test') 142 | plt.legend() 143 | plt.grid() 144 | plt.savefig('MSEacc.jpg', dpi = 1800) 145 | plt.show() 146 | 147 | 148 | 149 | if __name__=='__main__': 150 | import numpy as np 151 | from matplotlib import pyplot as plt 152 | main() -------------------------------------------------------------------------------- /18308013-陈家豪-assignment1/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/18308013-陈家豪-assignment1/report.pdf -------------------------------------------------------------------------------- /18308013-陈家豪-assignment2/code/SVM.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import numpy as np 3 | import time 4 | from sklearn import svm 5 | 6 | # 获取训练集数据 7 | train_images = np.load("material/train-images.npy") 8 | train_labels = np.load("material/train-labels.npy") 9 | # 添加偏置1 10 | extend = np.ones(train_images.shape[0]) 11 | train_X = np.c_[extend, train_images] 12 | train_Y = train_labels 13 | # 特征标准化 14 | meanVal = [] 15 | stdVal = [] 16 | for i in range(train_X.shape[1]): 17 | meanVal.append(np.mean(train_X[:, i])) 18 | stdVal.append(np.std(train_X[:,i])) 19 | if stdVal[i] != 0: 20 | train_X[:, i] = (train_X[:,i]-meanVal[i])/stdVal[i] 21 | # 打乱数据 22 | state = np.random.get_state() 23 | np.random.shuffle(train_X) 24 | np.random.set_state(state) 25 | np.random.shuffle(train_Y) 26 | 27 | # 获取测试集数据 28 | test_images = np.load("material/test-images.npy") 29 | test_labels = np.load("material/test-labels.npy") 30 | # 添加偏置1 31 | extend = np.ones(test_images.shape[0]) 32 | test_X = np.c_[extend, test_images] 33 | test_Y = test_labels 34 | # 特征标准化 35 | for i in range(test_X.shape[1]): 36 | if stdVal[i] != 0: 37 | test_X[:, i] = (test_X[:,i]-meanVal[i])/stdVal[i] 38 | # 打乱数据 39 | state = np.random.get_state() 40 | np.random.shuffle(test_X) 41 | np.random.set_state(state) 42 | np.random.shuffle(test_Y) 43 | 44 | # 线性核SVM初始化与训练 45 | LinearSvc = svm.SVC(C=1.0, kernel='linear', random_state=0) 46 | time_start = time.time() 47 | model1 = LinearSvc.fit(train_X, train_Y) 48 | time_end = time.time() 49 | # 显示准确率 50 | print("--------- Linear SVM ---------") 51 | print("time use:\t%f"%(time_end-time_start)) 52 | print("train acc:\t%f"%(model1.score(train_X,train_Y))) 53 | print("test acc:\t%f"%(model1.score(test_X,test_Y))) 54 | 55 | # 高斯核SVM初始化与训练 56 | RbfSvc = svm.SVC(C=1.0, kernel='rbf', random_state=0, gamma='auto') 57 | time_start = time.time() 58 | model2 = RbfSvc.fit(train_X, train_Y) 59 | time_end = time.time() 60 | # 显示准确率 61 | print("---------- RBF SVM ----------") 62 | print("time use:\t%f"%(time_end-time_start)) 63 | print("train:\t\t%f"%(model2.score(train_X,train_Y))) 64 | print("test:\t\t%f"%(model2.score(test_X,test_Y))) -------------------------------------------------------------------------------- /18308013-陈家豪-assignment2/code/linear_classify.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | def sigmoid(x): 3 | if x > 0: 4 | return 1/(1+np.exp(-x)) 5 | else: 6 | return np.exp(x)/(np.exp(x)+1) 7 | 8 | def train(func, W, train_X, train_Y, Lambda, learning_rate): 9 | if func=='hinge': 10 | temp = np.dot(train_X, W)*train_Y 11 | temp2 = np.zeros_like(temp) 12 | for i in range(temp.shape[0]): 13 | if temp[i]<1: 14 | temp2[i,0] = -1 15 | dW = (1/train_X.shape[0])*np.dot(train_X.T, temp2*train_Y) + Lambda*W 16 | W -= learning_rate*dW 17 | return W 18 | elif func=='cross': 19 | temp = np.dot(train_X, W) 20 | for i in range(temp.shape[0]): 21 | temp[i,0] = sigmoid(temp[i,0]) 22 | dW = (1/train_X.shape[0])*np.dot(train_X.T, temp-train_Y) + Lambda*W 23 | W -= learning_rate*dW 24 | return W 25 | 26 | def predict(func, W, X): 27 | prediction = np.dot(X, W) 28 | if func=='hinge': 29 | for i in range(prediction.shape[0]): 30 | if prediction[i,0]>0: 31 | prediction[i,0] = 1 32 | elif prediction[i,0]<0: 33 | prediction[i,0] = -1 34 | return prediction 35 | elif func=='cross': 36 | for i in range(prediction.shape[0]): 37 | if prediction[i,0]>=0: 38 | prediction[i,0] = 1 39 | else: 40 | prediction[i,0] = 0 41 | return prediction 42 | 43 | def accuracy(prediction, labels_Y): 44 | current = 0 45 | for i in range(prediction.size): 46 | if int(prediction[i,0])==int(labels_Y[i,0]): 47 | current += 1 48 | return current/prediction.size 49 | 50 | def HingeLoss(W, X, Y): 51 | temp = np.dot(X, W)*Y 52 | loss = 0.0 53 | for i in range(temp.shape[0]): 54 | if temp[i,0]<1: 55 | loss += 1-temp[i,0] 56 | return loss/X.shape[0] 57 | 58 | def CrossEntropyLoss(W, X, Y): 59 | temp = np.dot(X, W) 60 | loss = 0.0 61 | for i in range(temp.shape[0]): 62 | if int(Y[i,0]) == 1: 63 | loss += np.log(sigmoid(temp[i,0])) 64 | else: 65 | loss += np.log(1-sigmoid(temp[i,0])) 66 | loss *= -(1/X.shape[0]) 67 | return loss 68 | 69 | def main(): 70 | # 超参数设置 71 | epochs = 100 72 | learning_rate = 0.005 73 | BATCH_SIZE = 512 74 | LAMBDA = 0.01 75 | K = 10 76 | 77 | # 获取训练集数据 78 | train_images = np.load("material/train-images.npy") 79 | train_labels = np.load("material/train-labels.npy") 80 | # 添加偏置1 81 | extend = np.ones(train_images.shape[0]) 82 | train_X = np.c_[extend, train_images] 83 | # {0, 1}标签类型 84 | train_Y = np.reshape(train_labels, (-1,1)) 85 | # {-1, 1}标签类型 86 | train_Y2 = np.zeros((train_labels.size,1)) 87 | for i in range(train_labels.size): 88 | if train_labels[i]==1: 89 | train_Y2[i,0] = 1 90 | else: 91 | train_Y2[i,0] = -1 92 | # 特征标准化 93 | meanVal = [] 94 | stdVal = [] 95 | for i in range(train_X.shape[1]): 96 | meanVal.append(np.mean(train_X[:, i])) 97 | stdVal.append(np.std(train_X[:,i])) 98 | if stdVal[i] != 0: 99 | train_X[:, i] = (train_X[:,i]-meanVal[i])/stdVal[i] 100 | 101 | # 获取测试集数据 102 | test_images = np.load("material/test-images.npy") 103 | test_labels = np.load("material/test-labels.npy") 104 | # 添加偏置1 105 | extend = np.ones(test_images.shape[0]) 106 | test_X = np.c_[extend, test_images] 107 | # {0, 1}标签类型 108 | test_Y = np.reshape(test_labels, (-1,1)) 109 | # {-1, 1}标签类型 110 | test_Y2 = np.zeros((test_labels.size,1)) 111 | for i in range(test_labels.size): 112 | if test_labels[i]==1: 113 | test_Y2[i,0] = 1 114 | else: 115 | test_Y2[i,0] = -1 116 | # 特征标准化 117 | for i in range(test_X.shape[1]): 118 | if stdVal[i] != 0: 119 | test_X[:, i] = (test_X[:,i]-meanVal[i])/stdVal[i] 120 | 121 | # 设置参数矩阵 122 | np.random.seed(0) 123 | W = np.random.rand(train_X.shape[1], 1) 124 | # cross-entropy loss模型训练 125 | train_loss = [] 126 | valid_loss = [] 127 | train_acc = [] 128 | test_acc =[] 129 | time_start = time.time() 130 | for i in range(epochs): 131 | # 打乱训练集数据和标签 132 | state = np.random.get_state() 133 | np.random.shuffle(train_X) 134 | np.random.set_state(state) 135 | np.random.shuffle(train_Y) 136 | np.random.set_state(state) 137 | np.random.shuffle(train_Y2) 138 | # K折交叉验证 139 | block_size = int(train_X.shape[0]/K) 140 | train_loss.append(0) 141 | valid_loss.append(0) 142 | for k in range(K): 143 | ValidBlock_X = train_X[k*block_size:(k+1)*block_size, :] 144 | ValidBlock_Y = train_Y[k*block_size:(k+1)*block_size, :] 145 | TrainBlock_X = np.r_[train_X[:k*block_size, :], train_X[(k+1)*block_size:, :]] 146 | TrainBlock_Y = np.r_[train_Y[:k*block_size, :], train_Y[(k+1)*block_size:, :]] 147 | # mini-batch 148 | for Idx in range(int(TrainBlock_X.shape[0]/BATCH_SIZE)): 149 | # 获取索引 150 | StartIdx = Idx*BATCH_SIZE 151 | EndIdx = StartIdx+BATCH_SIZE 152 | if EndIdx > TrainBlock_X.shape[0]: 153 | EndIdx = TrainBlock_X.shape[0] 154 | W = train('cross', W, TrainBlock_X[StartIdx:EndIdx,:], TrainBlock_Y[StartIdx:EndIdx,:], LAMBDA, learning_rate) 155 | # 计算损失值 156 | train_loss[-1] += CrossEntropyLoss(W, TrainBlock_X, TrainBlock_Y) 157 | valid_loss[-1] += CrossEntropyLoss(W, ValidBlock_X, ValidBlock_Y) 158 | train_loss[-1] /= K 159 | valid_loss[-1] /= K 160 | if (i+1)%1 == 0: 161 | train_acc.append(accuracy(predict('cross', W, train_X), train_Y)) 162 | test_acc.append(accuracy(predict('cross', W, test_X), test_Y)) 163 | print("%d/%d:\tAvgTrainLoss = %.6f\tAvgValidLoss = %.6f\tTotalTrainAcc = %.6f\tTotalTestAcc = %.6f"%(i+1, epochs, train_loss[-1], valid_loss[-1], train_acc[-1], test_acc[-1])) 164 | time_end = time.time() 165 | print("time use:%f"%(time_end-time_start)) 166 | 167 | # 设置参数矩阵 168 | np.random.seed(0) 169 | W2 = np.random.rand(train_X.shape[1], 1) 170 | # hinge loss模型训练 171 | train_loss2 = [] 172 | valid_loss2 = [] 173 | train_acc2 = [] 174 | test_acc2 =[] 175 | time_start = time.time() 176 | for i in range(epochs): 177 | # 打乱训练集数据和标签 178 | state = np.random.get_state() 179 | np.random.shuffle(train_X) 180 | np.random.set_state(state) 181 | np.random.shuffle(train_Y) 182 | np.random.set_state(state) 183 | np.random.shuffle(train_Y2) 184 | # K折交叉验证 185 | block_size = int(train_X.shape[0]/K) 186 | train_loss2.append(0) 187 | valid_loss2.append(0) 188 | for k in range(K): 189 | ValidBlock_X = train_X[k*block_size:(k+1)*block_size, :] 190 | ValidBlock_Y = train_Y2[k*block_size:(k+1)*block_size, :] 191 | TrainBlock_X = np.r_[train_X[:k*block_size, :], train_X[(k+1)*block_size:, :]] 192 | TrainBlock_Y = np.r_[train_Y2[:k*block_size, :], train_Y2[(k+1)*block_size:, :]] 193 | # mini-batch 194 | for Idx in range(int(TrainBlock_X.shape[0]/BATCH_SIZE)): 195 | # 获取索引 196 | StartIdx = Idx*BATCH_SIZE 197 | EndIdx = StartIdx+BATCH_SIZE 198 | if EndIdx > TrainBlock_X.shape[0]: 199 | EndIdx = TrainBlock_X.shape[0] 200 | W2 = train('hinge', W2, TrainBlock_X[StartIdx:EndIdx,:], TrainBlock_Y[StartIdx:EndIdx,:], LAMBDA, learning_rate) 201 | # 计算损失值 202 | train_loss2[-1] += HingeLoss(W2, TrainBlock_X, TrainBlock_Y) 203 | valid_loss2[-1] += HingeLoss(W2, ValidBlock_X, ValidBlock_Y) 204 | train_loss2[-1] /= K 205 | valid_loss2[-1] /= K 206 | if (i+1)%1 == 0: 207 | train_acc2.append(accuracy(predict('hinge', W2, train_X), train_Y2)) 208 | test_acc2.append(accuracy(predict('hinge', W2, test_X), test_Y2)) 209 | print("%d/%d:\tAvgTrainLoss = %.6f\tAvgValidLoss = %.6f\tTotalTrainAcc = %.6f\tTotalTestAcc = %.6f"%(i+1, epochs, train_loss2[-1], valid_loss2[-1], train_acc2[-1], test_acc2[-1])) 210 | time_end = time.time() 211 | print("time use:%f"%(time_end-time_start)) 212 | 213 | # 画图 214 | plt.figure() 215 | plt.xlabel("epochs") 216 | plt.ylabel("loss") 217 | plt.xticks(range(0, epochs+1, 10)) 218 | plt.plot(range(epochs), train_loss, c='red', label='train') 219 | plt.plot(range(epochs), valid_loss, c='green', label='valid') 220 | plt.legend() 221 | plt.grid() 222 | plt.savefig('CrossLoss.jpg', dpi = 900) 223 | plt.show() 224 | 225 | plt.figure() 226 | plt.xlabel("epochs") 227 | plt.ylabel("loss") 228 | plt.xticks(range(0, epochs+1, 10)) 229 | plt.plot(range(epochs), train_loss2, c='red', label='train') 230 | plt.plot(range(epochs), valid_loss2, c='green', label='valid') 231 | plt.legend() 232 | plt.grid() 233 | plt.savefig('HingeLoss.jpg', dpi = 900) 234 | plt.show() 235 | 236 | plt.figure() 237 | plt.xlabel("epochs") 238 | plt.ylabel("loss") 239 | plt.xticks(range(0, epochs+1, 10)) 240 | plt.plot(range(epochs), train_acc, label='Cross Train') 241 | plt.plot(range(epochs), train_acc2, label='Hinge Train') 242 | plt.plot(range(epochs), test_acc, label=' Cross Test') 243 | plt.plot(range(epochs), test_acc2, label=' Hinge Test') 244 | plt.legend() 245 | plt.grid() 246 | plt.savefig('acc.jpg', dpi = 900) 247 | plt.show() 248 | 249 | if __name__=='__main__': 250 | import numpy as np 251 | import time 252 | from matplotlib import pyplot as plt 253 | main() -------------------------------------------------------------------------------- /18308013-陈家豪-assignment2/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/18308013-陈家豪-assignment2/report.pdf -------------------------------------------------------------------------------- /18308013-陈家豪-assignment3/code/code.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | import time 4 | import torch 5 | import random 6 | import torch.nn as nn 7 | import torch.nn.functional as F 8 | import torch.optim as optim 9 | from torch.utils.data import Dataset, DataLoader 10 | from torchsummary import summary 11 | 12 | BATCH_SIZE = 512 13 | EPOCHS = 50 14 | DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") 15 | 16 | class MyDataset(Dataset): 17 | def __init__(self, imageData, imageLabel): 18 | self.data = torch.from_numpy(imageData).float() 19 | self.data = self.data.permute(0, 3, 1, 2).contiguous()# (x,y,z,3)->(x,3,y,z) 20 | self.label = torch.from_numpy(imageLabel) 21 | def __len__(self): 22 | return self.data.shape[0] 23 | def __getitem__(self, idx): 24 | return self.data[idx], self.label[idx] 25 | 26 | 27 | class LinearNet(nn.Module): 28 | def __init__(self): 29 | super(LinearNet, self).__init__() 30 | self.fc1 = nn.Linear(3*32*32, 10) 31 | def forward(self, x): 32 | inSize = x.size(0) 33 | out = x.view(inSize, -1) 34 | out = self.fc1(out) 35 | out = F.log_softmax(out, dim=1) 36 | return out 37 | 38 | 39 | class MlpNet(nn.Module): 40 | def __init__(self): 41 | super(MlpNet, self).__init__() 42 | self.fc1 = nn.Linear(3*32*32, 1024) 43 | self.fc2 = nn.Linear(1024, 256) 44 | self.fc3 = nn.Linear(256, 64) 45 | self.fc4 = nn.Linear(64, 10) 46 | def forward(self, x): 47 | inSize = x.size(0) 48 | out = x.view(inSize, -1) 49 | out = self.fc1(out) 50 | out = F.relu(out) 51 | out = self.fc2(out) 52 | out = F.relu(out) 53 | out = self.fc3(out) 54 | out = F.relu(out) 55 | out = self.fc4(out) 56 | out = F.log_softmax(out, dim=1) 57 | return out 58 | 59 | 60 | class CnnNet(nn.Module): 61 | def __init__(self): 62 | super(CnnNet, self).__init__() 63 | self.conv1 = nn.Conv2d(3, 6, 5) 64 | self.conv2 = nn.Conv2d(6, 16, 5) 65 | self.fc1 = nn.Linear(400, 120) 66 | self.fc2 = nn.Linear(120, 84) 67 | self.fc3 = nn.Linear(84, 10) 68 | def forward(self, x): 69 | inSize = x.size(0) 70 | out = F.relu(self.conv1(x)) # batch*3*32*32->batch*6*28*28 71 | out = F.max_pool2d(out, 2, 2) # batch*6*28*28->batch*6*14*14 72 | out = F.relu(self.conv2(out)) # batch*6*14*14->batch*16*10*10 73 | out = F.max_pool2d(out, 2, 2) # batch*16*10*10->batch*16*5*5 74 | out = out.view(inSize, -1) # batch*16*5*5->batch*400 75 | out = F.relu(self.fc1(out)) # batch*400->batch*120 76 | out = F.relu(self.fc2(out)) # batch*120->batch*84 77 | out = self.fc3(out) # batch*84->batch*10 78 | out = F.log_softmax(out, dim=1) 79 | return out 80 | 81 | 82 | def train(model, device, train_loader, optimizer, epoch, lossList, accList): 83 | ''' 84 | 训练函数 85 | ''' 86 | model.train() 87 | trainLoss = 0 88 | correct = 0 89 | for batch_idx, (data, target) in enumerate(train_loader): 90 | data, target = data.to(device), target.to(device) 91 | optimizer.zero_grad() 92 | output = model(data) 93 | loss = F.nll_loss(output, target) 94 | with torch.no_grad(): 95 | trainLoss += loss.item() 96 | pred = output.max(1, keepdim=True)[1] # 找到概率最大的下标 97 | correct += pred.eq(target.view_as(pred)).sum().item() 98 | 99 | loss.backward() 100 | optimizer.step() 101 | if(batch_idx+1)%10 == 0: 102 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( 103 | epoch, batch_idx * len(data), len(train_loader.dataset), 104 | 100. * batch_idx / len(train_loader), loss.item())) 105 | trainLoss /= math.ceil(len(train_loader.dataset)/BATCH_SIZE) 106 | lossList.append(trainLoss) 107 | accList.append(correct / len(train_loader.dataset)) 108 | print('Train set: Average loss: {:.4f}, Accuracy: {}/{} ({:.4f}%)'.format( 109 | lossList[-1], correct, len(train_loader.dataset), 110 | 100. * accList[-1])) 111 | 112 | 113 | def test(model, device, test_loader, lossList, accList, setType='Test'): 114 | ''' 115 | 测试函数 116 | ''' 117 | model.eval() 118 | testLoss = 0 119 | correct = 0 120 | with torch.no_grad(): 121 | for data, target in test_loader: 122 | data, target = data.to(device), target.to(device) 123 | output = model(data) 124 | testLoss += F.nll_loss(output, target, reduction='sum').item() # 将一批的损失相加 125 | pred = output.max(1, keepdim=True)[1] # 找到概率最大的下标 126 | correct += pred.eq(target.view_as(pred)).sum().item() 127 | 128 | testLoss /= len(test_loader.dataset) 129 | lossList.append(testLoss) 130 | accList.append(correct / len(test_loader.dataset)) 131 | print(setType+' set: Average loss: {:.4f}, Accuracy: {}/{} ({:.4f}%)'.format( 132 | lossList[-1], correct, len(test_loader.dataset), 133 | 100. * accList[-1])) 134 | 135 | 136 | def fit(model, optimizer, trainLoader, validLoader, testLoader): 137 | trainLossList = list() 138 | trainAccList = list() 139 | validLossList = list() 140 | validAccList = list() 141 | testLossList = list() 142 | testAccList = list() 143 | startTime = time.time() 144 | for epoch in range(1, EPOCHS + 1): 145 | train(model, DEVICE, trainLoader, optimizer, epoch, trainLossList, trainAccList) 146 | test(model, DEVICE, validLoader, validLossList, validAccList, 'Valid') 147 | test(model, DEVICE, testLoader, testLossList, testAccList, 'Test') 148 | endTime = time.time() 149 | print('\n Total Time: {:.4f}\n'.format(endTime-startTime)) 150 | 151 | 152 | def main(): 153 | # 读取数据集 154 | train_images = np.load("material/cifar10_train_images.npy") 155 | train_labels = np.load("material/cifar10_train_labels.npy") 156 | test_images = np.load("material/cifar10_test_images.npy") 157 | test_labels = np.load("material/cifar10_test_labels.npy") 158 | # [0,255]->[0,1] 159 | train_images = train_images / 255 160 | test_images = test_images / 255 161 | # 打乱训练集数据,划分验证集 162 | np.random.seed(0) 163 | state = np.random.get_state() 164 | np.random.shuffle(train_images) 165 | np.random.set_state(state) 166 | np.random.shuffle(train_labels) 167 | valid_images = train_images[int(train_images.shape[0]*0.8):,:,:,:] 168 | valid_labels = train_labels[int(train_labels.shape[0]*0.8):] 169 | train_images = train_images[:int(train_images.shape[0]*0.8),:,:,:] 170 | train_labels = train_labels[:int(train_labels.shape[0]*0.8)] 171 | # 显示训练集、验证集和测试集的shape 172 | print(train_images.shape) #(40000, 32, 32, 3) 173 | print(train_labels.shape) #(40000, ) 174 | print(valid_images.shape) #(10000, 32, 32, 3) 175 | print(valid_labels.shape) #(10000, ) 176 | print(test_images.shape) #(10000, 32, 32, 3) 177 | print(test_labels.shape) #(10000, ) 178 | 179 | # 封装数据集 180 | trainDataset = MyDataset(train_images, train_labels) 181 | validDataset = MyDataset(valid_images, valid_labels) 182 | testDataset = MyDataset(test_images, test_labels) 183 | # 加载数据集 184 | trainLoader = DataLoader(trainDataset, batch_size = BATCH_SIZE, shuffle =True) 185 | validLoader = DataLoader(validDataset, batch_size = BATCH_SIZE, shuffle = True) 186 | testLoader = DataLoader(testDataset, batch_size = BATCH_SIZE, shuffle = True) 187 | 188 | # 加载模型和优化器 189 | linearModel = LinearNet().to(DEVICE) 190 | linearOptimizer = optim.Adam(linearModel.parameters()) 191 | summary(linearModel, input_size=(3,32,32)) 192 | # 训练与测试线性分类器 193 | fit(linearModel, linearOptimizer, trainLoader, validLoader, testLoader) 194 | 195 | # 加载模型和优化器 196 | mlpModel = MlpNet().to(DEVICE) 197 | mlpOptimizer = optim.Adam(mlpModel.parameters()) 198 | summary(mlpModel, input_size=(3,32,32)) 199 | # 训练与测试MLP 200 | fit(mlpModel, mlpOptimizer, trainLoader, validLoader, testLoader) 201 | 202 | # 加载模型和优化器 203 | cnnModel = CnnNet().to(DEVICE) 204 | cnnOptimizer = optim.Adam(cnnModel.parameters()) 205 | summary(cnnModel, input_size=(3,32,32)) 206 | # 训练与测试CNN 207 | fit(cnnModel, cnnOptimizer, trainLoader, validLoader, testLoader) 208 | 209 | 210 | if __name__=='__main__': 211 | main() -------------------------------------------------------------------------------- /18308013-陈家豪-assignment3/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/18308013-陈家豪-assignment3/report.pdf -------------------------------------------------------------------------------- /18308013-陈家豪-assignment4/code/code.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | import time 4 | from scipy.stats import multivariate_normal 5 | from sklearn.decomposition import PCA 6 | from scipy.linalg import pinvh 7 | from munkres import Munkres, print_matrix 8 | EPOCHS = 20 9 | NEW_DIMENSION = 60 10 | 11 | class myKmeans(): 12 | def __init__(self, init_data, K=2, init_method='random'): 13 | ''' 14 | Description 15 | ---------- 16 | K-Means 17 | 18 | Parameters 19 | ---------- 20 | init_data : ndarray (numbers, dimensions) 21 | 用于初始化模型参数的样本数据 22 | 23 | K : int 24 | 聚类数 25 | 26 | init_method : string 27 | 初始化方法: 'random', 'distance' or 'random+distance' 28 | ''' 29 | self.K = K # 聚类数 30 | self.dimension = init_data.shape[1] # 样本维度 31 | self.centroids = None # 聚类中心 32 | self.initCentroids(init_data, init_method) 33 | 34 | def initCentroids(self, data, init_method): 35 | ''' 36 | Description 37 | ---------- 38 | 初始化聚类中心 39 | 40 | Parameters 41 | ---------- 42 | data : ndarray (numbers, dimensions) 43 | 样本数据 44 | 45 | init_method : string 46 | 'random', 'distance' or 'random+distance' 47 | 48 | Returns 49 | ---------- 50 | None 51 | ''' 52 | assert len(data.shape)==2, "data must be a matrix" 53 | assert data.shape[0]>=self.K, "The number of data must be larger than K" 54 | # 获取并打乱样本数据的索引 55 | indexes = np.arange(data.shape[0]) 56 | np.random.shuffle(indexes) 57 | 58 | if init_method=='random': 59 | # 随机选择K个样本数据作为聚类中心 60 | self.centroids = np.zeros((self.K, data.shape[1])) 61 | for i in range(self.K): 62 | self.centroids[i] = data[indexes[i]] 63 | elif init_method=='distance': 64 | # 随机选择1个样本数据作为聚类中心, 65 | # 然后依次选取与当前聚类中心最远的样本作为聚类中心 66 | self.centroids = np.zeros((1, data.shape[1])) 67 | usedIndexes = list() 68 | for i in range(self.K): 69 | if i==0: 70 | # 随机选择一个 71 | self.centroids[i] = data[indexes[i]] 72 | usedIndexes.append(indexes[i]) 73 | else: 74 | # 计算其余样本离当前聚类中心的总距离 75 | distances = self.getDistance(data) 76 | totalDistances = np.sum(distances, axis=1) 77 | # 获取从远到近的排序 78 | indexes = np.argsort(-totalDistances) 79 | for index in indexes: 80 | if index not in usedIndexes: 81 | self.centroids = np.insert(self.centroids, obj=self.centroids.shape[0], values=data[index], axis=0) 82 | usedIndexes.append(index) 83 | break 84 | elif init_method=='random+distance': 85 | # 随机选择1个样本数据作为聚类中心, 86 | # 然后依次从与当前聚类中心最远的样本中随机选取作为聚类中心 87 | self.centroids = np.zeros((1, data.shape[1])) 88 | usedFlags = np.zeros(data.shape[0], dtype=int) 89 | for i in range(self.K): 90 | if i==0: 91 | # 随机选择一个 92 | self.centroids[i] = data[indexes[i]] 93 | usedFlags[indexes[i]] = 1 94 | else: 95 | # 获取没选的样本索引 96 | unusedIndexes = np.argsort(usedFlags) 97 | unusedIndexes = unusedIndexes[:-i] 98 | # 计算没选的样本离聚类中心的总距离 99 | distances = self.getDistance(data[unusedIndexes,:]) 100 | totalDistances = np.sum(distances, axis=1) 101 | # 从远到近排序 102 | DistancesIndexes = np.argsort(-totalDistances) 103 | while True: 104 | # 随机抽号,位于前50%且没被选过时即为新聚类中心 105 | index = unusedIndexes[random.randint(0,unusedIndexes.size-1)] 106 | if index in unusedIndexes[DistancesIndexes[:int(np.ceil(float(DistancesIndexes.size)/2))]]: 107 | usedFlags[index] = 1 108 | self.centroids = np.insert(self.centroids, obj=self.centroids.shape[0], values=data[index], axis=0) 109 | break 110 | 111 | def getDistance(self, data): 112 | ''' 113 | Description 114 | ---------- 115 | 获取data与各个聚类中心的距离 116 | 117 | Parameters 118 | ---------- 119 | data : ndarray (numbers, dimensions) 120 | 样本数据 121 | 122 | Returns 123 | ---------- 124 | distances : ndarray (numbers, K) 125 | distances[i,k]表示第i个样本与第k个聚类中心的欧式距离 126 | ''' 127 | distances = np.zeros((data.shape[0], self.centroids.shape[0])) 128 | for i in range(data.shape[0]): 129 | distances[i] = np.sum((self.centroids - data[i])**2, axis=1)**0.5 130 | return distances 131 | 132 | def getClusters(self, data): 133 | ''' 134 | Description 135 | ---------- 136 | 获取各个样本的所属聚类,以及离所属聚类中心的平均距离 137 | 138 | Parameters 139 | ---------- 140 | data : ndarray (numbers, dimensions) 141 | 样本数据 142 | 143 | Returns 144 | ---------- 145 | clusters : ndarray (numbers, ) 146 | 各个样本所属聚类 147 | avgDistances : ndarray (numbers, ) 148 | 各个样本离所属聚类中心的平均距离 149 | ''' 150 | distances = self.getDistance(data) 151 | clusters = np.argmin(distances, axis=1) 152 | avgDistances = np.sum(np.min(distances, axis=1))/data.shape[0] 153 | return clusters, avgDistances 154 | 155 | def getCentroids(self, data, clusters): 156 | ''' 157 | Description 158 | ---------- 159 | 获取新的聚类中心 160 | 161 | Parameters 162 | ---------- 163 | data : ndarray (numbers, dimensions) 164 | 样本数据 165 | clusters : ndarray (numbers, ) 166 | 各个样本所属聚类 167 | 168 | Returns 169 | ---------- 170 | centroids : ndarray (K, dimensions) 171 | 各个聚类中心 172 | ''' 173 | oneHotClusters = np.zeros((data.shape[0], self.K)) 174 | oneHotClusters[clusters[:,None]==np.arange(self.K)] = 1 175 | return np.dot(oneHotClusters.T, data)/np.sum(oneHotClusters, axis=0).reshape((-1,1)) 176 | 177 | def getAccuracy(self, predLabels, trueLabels): 178 | ''' 179 | Description 180 | ---------- 181 | 计算准确率 182 | 183 | Parameters 184 | ---------- 185 | predLabels : ndarray (numbers, ) 186 | 样本的预测聚类标签 187 | trueLabels : ndarray (numbers, ) 188 | 样本的真实聚类标签 189 | 190 | Returns 191 | ---------- 192 | accuracy : float 193 | 准确率 194 | ''' 195 | assert predLabels.size==trueLabels.size, "predLabels.size must be equal to trueLabels.size" 196 | # 获取标签类型 197 | predLabelType = np.unique(predLabels) 198 | trueLabelType = np.unique(trueLabels) 199 | # 获取标签数量 200 | labelNum = np.maximum(len(predLabelType), len(trueLabelType)) 201 | # 计算代价矩阵 202 | costMatrix = np.zeros((labelNum, labelNum)) 203 | for i in range(len(predLabelType)): 204 | chosenPredLabels = (predLabels==predLabelType[i]).astype(float) 205 | for j in range(len(trueLabelType)): 206 | chosenTrueLabels = (trueLabels==trueLabelType[j]).astype(float) 207 | costMatrix[i,j] = -np.sum(chosenPredLabels*chosenTrueLabels) 208 | # 匈牙利算法 209 | m = Munkres() 210 | # 获取标签映射 211 | indexes = m.compute(costMatrix) 212 | # 获取映射后的预测标签 213 | mappedPredLabels = np.zeros_like(predLabels, dtype=int) 214 | for index1,index2 in indexes: 215 | if index1(batch, TRANS_CONV_SIZE*4, 4, 4) 38 | out = self.batchNorm1(out) 39 | out = F.relu(out) 40 | out = self.convTranspose2(out) # (batch, TRANS_CONV_SIZE*4, 4, 4)->(batch, TRANS_CONV_SIZE*2, 8, 8) 41 | out = self.batchNorm2(out) 42 | out = F.relu(out) 43 | out = self.convTranspose3(out) # (batch, TRANS_CONV_SIZE*2, 8, 8)->(batch, TRANS_CONV_SIZE, 16, 16) 44 | out = self.batchNorm3(out) 45 | out = F.relu(out) 46 | out = self.convTranspose4(out) # (batch, TRANS_CONV_SIZE, 16, 16)->(batch, CHANNEL_NUM, 32, 32) 47 | out = torch.tanh(out) 48 | return out 49 | 50 | class Discriminator(nn.Module): 51 | def __init__(self): 52 | super(Discriminator, self).__init__() 53 | self.conv1 = nn.Conv2d(CHANNEL_NUM, CONV_SIZE, 4, 2, 1, bias=False) 54 | self.conv2 = nn.Conv2d(TRANS_CONV_SIZE, CONV_SIZE*2, 4, 2, 1, bias=False) 55 | self.batchNorm1 = nn.BatchNorm2d(CONV_SIZE*2) 56 | self.conv3 = nn.Conv2d(TRANS_CONV_SIZE*2, CONV_SIZE*4, 4, 2, 1, bias=False) 57 | self.batchNorm2 = nn.BatchNorm2d(CONV_SIZE*4) 58 | self.conv4 = nn.Conv2d(CONV_SIZE*4, 1, 4, 1, 0, bias=False) 59 | 60 | def forward(self, x): 61 | out = self.conv1(x) # (batch, channels, 32, 32)->(batch, TRANS_CONV_SIZE, 16, 16) 62 | out = F.leaky_relu(out, 0.2, True) 63 | out = self.conv2(out) # (batch, TRANS_CONV_SIZE, 16, 16)->(batch, TRANS_CONV_SIZE*2, 8, 8) 64 | out = self.batchNorm1(out) 65 | out = F.leaky_relu(out, 0.2, True) 66 | out = self.conv3(out) # (batch, TRANS_CONV_SIZE*2, 8, 8)->(batch, TRANS_CONV_SIZE*4, 4, 4) 67 | out = self.batchNorm2(out) 68 | out = F.leaky_relu(out, 0.2, True) 69 | out = self.conv4(out) # (batch, TRANS_CONV_SIZE*4, 4, 4)->(batch, 1, 1, 1) 70 | out = torch.sigmoid(out) 71 | return out 72 | 73 | def initWeight(m): 74 | classname = m.__class__.__name__ 75 | if classname.find('Conv') != -1: 76 | nn.init.normal_(m.weight.data, 0.0, 0.02) 77 | elif classname.find('BatchNorm') != -1: 78 | nn.init.normal_(m.weight.data, 1.0, 0.02) 79 | nn.init.constant_(m.bias.data, 0) 80 | 81 | def train(generator_model, discriminator_model, device, train_loader, generator_optimizer, discriminator_optimizer, epoch, gLossList, dLossList, realScoreList, fakeScoreList1, fakeScoreList2): 82 | ''' 83 | 训练函数 84 | ''' 85 | generator_model.train() 86 | discriminator_model.train() 87 | gLossSum = 0 88 | dLossSum = 0 89 | realScoreSum = 0 90 | fakeScore1Sum = 0 91 | fakeScore2Sum = 0 92 | iters = 0 93 | for batch_idx, data in enumerate(train_loader): 94 | # 更新判别器参数 95 | # discriminator_model.zero_grad() 96 | discriminator_optimizer.zero_grad() 97 | # 计算真实图片的loss 98 | data = data.to(device) 99 | # 生成数据标签,真实label=1 100 | dataNum = data.size(0) 101 | realLabel = torch.ones(dataNum).to(device) 102 | # 将真实数据输入判别器 103 | realOutput = discriminator_model(data).view(-1) 104 | realLoss = F.binary_cross_entropy(realOutput, realLabel) 105 | realScore = realOutput.mean().item() 106 | # 计算伪造图片的loss 107 | # 生成随机噪声 108 | noise = torch.randn(dataNum, INT_DIMENSION,1,1).to(device) 109 | # 获得虚假图片 110 | fakeData = generator_model(noise) 111 | # 生成数据标签,虚假label=0 112 | fakeLabel = torch.zeros(dataNum).to(device) 113 | # 将虚假数据输入判别器 114 | fakeOutput = discriminator_model(fakeData.detach()).view(-1) 115 | fakeLoss = F.binary_cross_entropy(fakeOutput, fakeLabel) 116 | fakeScore1 = fakeOutput.mean().item() 117 | # 计算loss,更新梯度 118 | dLoss = realLoss + fakeLoss 119 | dLoss.backward() 120 | discriminator_optimizer.step() 121 | 122 | # 更新生成器参数 123 | # generator_model.zero_grad() 124 | generator_optimizer.zero_grad() 125 | # 获取生成图片在判别器的输出值 126 | output = discriminator_model(fakeData).view(-1) 127 | # 计算loss,更新梯度 128 | gLoss = F.binary_cross_entropy(output, realLabel) 129 | gLoss.backward() 130 | fakeScore2 = output.mean().item() 131 | generator_optimizer.step() 132 | 133 | # 输出结果 134 | if (batch_idx+1)%20==0: 135 | print('[{}/{}][{}/{}]\tLoss_D: {:.4f}\tLoss_G: {:.4f}\tD(x): {:.4f}\tD(G(z)): {:.4f}/{:.4f}'.format( 136 | epoch, EPOCHS, batch_idx+1, len(train_loader), 137 | dLoss.item(), gLoss.item(), realScore, fakeScore1, fakeScore2)) 138 | gLossSum += gLoss.item() 139 | dLossSum += dLoss.item() 140 | realScoreSum += realScore 141 | fakeScore1Sum += fakeScore1 142 | fakeScore2Sum += fakeScore2 143 | iters += 1 144 | gLossList.append(gLossSum/iters) 145 | dLossList.append(dLossSum/iters) 146 | realScoreList.append(realScoreSum/iters) 147 | fakeScoreList1.append(fakeScore1Sum/iters) 148 | fakeScoreList2.append(fakeScore2Sum/iters) 149 | 150 | def test(generator_model, discriminator_model, device, test_loader, gLossList, dLossList, realScoreList, fakeScoreList): 151 | ''' 152 | 训练函数 153 | ''' 154 | generator_model.train() 155 | discriminator_model.train() 156 | gLossSum = 0 157 | dLossSum = 0 158 | fakeScoreSum = 0 159 | realScoreSum = 0 160 | iters = 0 161 | with torch.no_grad(): 162 | for data in test_loader: 163 | # 计算真实图片的loss 164 | data = data.to(device) 165 | # 生成数据标签,真实label=1 166 | dataNum = data.size(0) 167 | realLabel = torch.ones(dataNum).to(device) 168 | # 将真实数据输入判别器 169 | realOutput = discriminator_model(data).view(-1) 170 | realLoss = F.binary_cross_entropy(realOutput, realLabel) 171 | realScore = realOutput.mean().item() 172 | # 计算伪造图片的loss 173 | # 生成随机噪声 174 | noise = torch.randn(dataNum, INT_DIMENSION,1,1).to(device) 175 | # 获得虚假图片 176 | fakeData = generator_model(noise) 177 | # 生成数据标签,虚假label=0 178 | fakeLabel = torch.zeros(dataNum).to(device) 179 | # 将虚假数据输入判别器 180 | fakeOutput = discriminator_model(fakeData).view(-1) 181 | fakeLoss = F.binary_cross_entropy(fakeOutput, fakeLabel) 182 | fakeScore = fakeOutput.mean().item() 183 | # 计算loss,更新梯度 184 | dLoss = realLoss + fakeLoss 185 | gLoss = F.binary_cross_entropy(fakeOutput, realLabel) 186 | # 输出结果 187 | gLossSum += gLoss.item() 188 | dLossSum += dLoss.item() 189 | fakeScoreSum += fakeScore 190 | realScoreSum += realScore 191 | iters += 1 192 | gLossList.append(gLossSum/iters) 193 | dLossList.append(dLossSum/iters) 194 | fakeScoreList.append(fakeScoreSum/iters) 195 | realScoreList.append(realScoreSum/iters) 196 | print('test\tLoss_D: {:.4f}\tLoss_G: {:.4f}\tD(x): {:.4f}\tD(G(z)): {:.4f}'.format( 197 | dLossList[-1], gLossList[-1], realScoreList[-1], fakeScoreList[-1])) 198 | 199 | def generate(generator_model, noise): 200 | with torch.no_grad(): 201 | fakeImg = generator_model(noise).cpu() 202 | return utils.make_grid(fakeImg, padding=2, normalize=True) 203 | 204 | def fit(generator_model, discriminator_model, generator_optimizer, discriminator_optimizer, trainLoader, testLoader, fixedNoise): 205 | train_gLossList = list() 206 | train_dLossList = list() 207 | train_realScoreList = list() 208 | train_fakeScoreList1 = list() 209 | train_fakeScoreList2 = list() 210 | test_gLossList = list() 211 | test_dLossList = list() 212 | test_realScoreList = list() 213 | test_fakeScoreList = list() 214 | imgList = list() 215 | for epoch in range(1, EPOCHS + 1): 216 | train(generator_model, discriminator_model, DEVICE, 217 | trainLoader, generator_optimizer, discriminator_optimizer, 218 | epoch, train_gLossList, train_dLossList, train_realScoreList, 219 | train_fakeScoreList1, train_fakeScoreList2) 220 | test(generator_model, discriminator_model, DEVICE, 221 | testLoader, test_gLossList, test_dLossList, test_realScoreList, 222 | test_fakeScoreList) 223 | imgList.append(generate(generator_model, fixedNoise)) 224 | return (train_gLossList,train_dLossList,train_realScoreList, 225 | train_fakeScoreList1,train_fakeScoreList2, 226 | test_gLossList,test_dLossList, 227 | test_realScoreList,test_fakeScoreList,imgList 228 | ) 229 | 230 | class MyDataset(Dataset): 231 | def __init__(self, imageData): 232 | self.data = torch.from_numpy(imageData).float() 233 | self.data = self.data.permute(0, 3, 1, 2).contiguous()# (x,y,z,3)->(x,3,y,z) 234 | def __len__(self): 235 | return self.data.shape[0] 236 | def __getitem__(self, idx): 237 | return self.data[idx] 238 | 239 | def main(): 240 | # 加载数据 241 | train_images = np.load("material/cifar10_train_images.npy") 242 | train_labels = np.load("material/cifar10_train_labels.npy") 243 | test_images = np.load("material/cifar10_test_images.npy") 244 | test_labels = np.load("material/cifar10_test_labels.npy") 245 | train_images = train_images / 255 246 | test_images = test_images / 255 247 | # 打乱训练集数据 248 | np.random.seed(0) 249 | state = np.random.get_state() 250 | np.random.shuffle(train_images) 251 | np.random.set_state(state) 252 | np.random.shuffle(train_labels) 253 | # 只获取标签为1的数据 254 | train_images = train_images[train_labels==1] 255 | test_images = test_images[test_labels==1] 256 | # normalize 257 | train_images = (train_images-np.array([0.5,0.5,0.5]))/np.array([0.5,0.5,0.5]) 258 | test_images = (test_images-np.array([0.5,0.5,0.5]))/np.array([0.5,0.5,0.5]) 259 | trainDataset = MyDataset(train_images) 260 | testDataset = MyDataset(test_images) 261 | trainLoader = DataLoader(trainDataset, batch_size = BATCH_SIZE, shuffle =True) 262 | testLoader = DataLoader(testDataset, batch_size = BATCH_SIZE, shuffle = True) 263 | # 查看真实图像 264 | plt.figure() 265 | realData = next(iter(trainLoader)) 266 | plt.axis("off") 267 | plt.title("Real Images") 268 | plt.imshow(np.transpose(utils.make_grid(realData.to(DEVICE)[:64], padding=2, normalize=True).cpu(),(1,2,0))) 269 | plt.savefig("output/real_images.png", dpi=400) 270 | plt.show() 271 | # 设置随机种子 272 | manualSeed = 999 273 | random.seed(manualSeed) 274 | torch.manual_seed(manualSeed) 275 | # 加载模型和优化器 276 | generator = Generator().to(DEVICE) 277 | generator.apply(initWeight) 278 | summary(generator, input_size=(INT_DIMENSION,1,1)) 279 | generatorOptimizer = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5,0.999)) 280 | 281 | discriminator = Discriminator().to(DEVICE) 282 | discriminator.apply(initWeight) 283 | summary(discriminator, input_size=(CHANNEL_NUM,32,32)) 284 | discriminatorOptimizer = optim.Adam(discriminator.parameters(),lr=0.0002, betas=(0.5,0.999)) 285 | # 训练拟合 286 | fixedNoise = torch.randn(64, INT_DIMENSION, 1, 1, device=DEVICE)# 固定噪声 287 | (train_gLossList,train_dLossList,train_realScoreList, 288 | train_fakeScoreList1,train_fakeScoreList2, 289 | test_gLossList,test_dLossList, 290 | test_realScoreList,test_fakeScoreList,imgList 291 | ) = fit(generator, discriminator, generatorOptimizer, discriminatorOptimizer, trainLoader, testLoader, fixedNoise) 292 | # 生成曲线图 293 | plt.figure() 294 | plt.xlabel("Epochs") 295 | plt.ylabel("Loss") 296 | plt.plot(range(EPOCHS), train_gLossList, label="generator train") 297 | plt.plot(range(EPOCHS), train_dLossList, label="discriminator train") 298 | plt.plot(range(EPOCHS), test_gLossList, label="generator test") 299 | plt.plot(range(EPOCHS), test_dLossList, label="discriminator test") 300 | plt.legend() 301 | plt.grid() 302 | plt.savefig("output/loss.png", dpi=400) 303 | plt.show() 304 | plt.figure() 305 | plt.xlabel("Epochs") 306 | plt.ylabel("Loss") 307 | plt.plot(range(EPOCHS), train_realScoreList, label="D(x) train") 308 | plt.plot(range(EPOCHS), train_fakeScoreList1, label="D1(G(z)) train") 309 | plt.plot(range(EPOCHS), train_fakeScoreList2, label="D2(G(z)) train") 310 | plt.plot(range(EPOCHS), test_realScoreList, label="D(x) test") 311 | plt.plot(range(EPOCHS), test_fakeScoreList, label="D(G(z)) test") 312 | plt.legend() 313 | plt.grid() 314 | plt.savefig("output/score.png", dpi=400) 315 | plt.show() 316 | # 比较真实图片和生成图片 317 | plt.figure() 318 | plt.subplot(1,2,1) 319 | plt.axis("off") 320 | plt.title("Real Images") 321 | plt.imshow(np.transpose(utils.make_grid(realData.to(DEVICE)[:64], padding=2, normalize=True).cpu(),(1,2,0))) 322 | 323 | plt.subplot(1,2,2) 324 | plt.axis("off") 325 | plt.title("Fake Images") 326 | plt.imshow(np.transpose(generate(generator, fixedNoise),(1,2,0))) 327 | plt.savefig("output/compare.png", dpi=400) 328 | plt.show() 329 | #将图片写入writer,生成gif 330 | with imageio.get_writer("output/output.gif", mode='I') as writer: 331 | for i in range(0,len(imgList)): 332 | writer.append_data(np.transpose(imgList[i],(1,2,0)).numpy()) 333 | 334 | if __name__=='__main__': 335 | main() -------------------------------------------------------------------------------- /18308013-陈家豪-assignment5/code/DCGAN_MNIST.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | import time 4 | import torch 5 | import random 6 | import torch.nn as nn 7 | import torch.nn.functional as F 8 | from torch.nn.modules.conv import ConvTranspose2d 9 | import torch.optim as optim 10 | from torch.utils.data import Dataset, DataLoader 11 | from torchvision import datasets, transforms,utils 12 | from torchsummary import summary 13 | import matplotlib.pyplot as plt 14 | import imageio 15 | 16 | BATCH_SIZE = 256 17 | EPOCHS = 200 18 | DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") 19 | 20 | INT_DIMENSION = 1000 21 | TRANS_CONV_SIZE = 16 22 | CONV_SIZE = 16 23 | CHANNEL_NUM = 1 24 | 25 | class Generator(nn.Module): 26 | def __init__(self): 27 | super(Generator, self).__init__() 28 | self.convTranspose1 = nn.ConvTranspose2d(INT_DIMENSION, TRANS_CONV_SIZE*4, 3, 1, 0, bias=False) 29 | self.batchNorm1 = nn.BatchNorm2d(TRANS_CONV_SIZE*4) 30 | self.convTranspose2 = nn.ConvTranspose2d(TRANS_CONV_SIZE*4, TRANS_CONV_SIZE*2, 3, 2, 0, bias=False) 31 | self.batchNorm2 = nn.BatchNorm2d(TRANS_CONV_SIZE*2) 32 | self.convTranspose3 = nn.ConvTranspose2d(TRANS_CONV_SIZE*2, TRANS_CONV_SIZE, 4, 2, 1, bias=False) 33 | self.batchNorm3 = nn.BatchNorm2d(TRANS_CONV_SIZE) 34 | self.convTranspose4 = nn.ConvTranspose2d(TRANS_CONV_SIZE, CHANNEL_NUM, 4, 2, 1, bias=False) 35 | 36 | def forward(self, x): 37 | out = self.convTranspose1(x) # (batch, INT_DIMENSION, 1, 1, 1)->(batch, TRANS_CONV_SIZE*4, 3, 3) 38 | out = self.batchNorm1(out) 39 | out = F.relu(out) 40 | out = self.convTranspose2(out) # (batch, TRANS_CONV_SIZE*4, 3, 3)->(batch, TRANS_CONV_SIZE*2, 7, 7) 41 | out = self.batchNorm2(out) 42 | out = F.relu(out) 43 | out = self.convTranspose3(out) # (batch, TRANS_CONV_SIZE*2, 7, 7)->(batch, TRANS_CONV_SIZE, 14, 14) 44 | out = self.batchNorm3(out) 45 | out = F.relu(out) 46 | out = self.convTranspose4(out) # (batch, TRANS_CONV_SIZE, 14, 14)->(batch, CHANNEL_NUM, 28, 28) 47 | out = torch.tanh(out) 48 | return out 49 | 50 | class Discriminator(nn.Module): 51 | def __init__(self): 52 | super(Discriminator, self).__init__() 53 | self.conv1 = nn.Conv2d(CHANNEL_NUM, CONV_SIZE, 4, 2, 1, bias=False) 54 | self.conv2 = nn.Conv2d(TRANS_CONV_SIZE, CONV_SIZE*2, 4, 2, 1, bias=False) 55 | self.batchNorm1 = nn.BatchNorm2d(CONV_SIZE*2) 56 | self.conv3 = nn.Conv2d(TRANS_CONV_SIZE*2, CONV_SIZE*4, 3, 2, 0, bias=False) 57 | self.batchNorm2 = nn.BatchNorm2d(CONV_SIZE*4) 58 | self.conv4 = nn.Conv2d(CONV_SIZE*4, 1, 3, 1, 0, bias=False) 59 | 60 | def forward(self, x): 61 | out = self.conv1(x) # (batch, channels, 28, 28)->(batch, TRANS_CONV_SIZE, 14, 14) 62 | out = F.leaky_relu(out, 0.2, True) 63 | out = self.conv2(out) # (batch, TRANS_CONV_SIZE, 14, 14)->(batch, TRANS_CONV_SIZE*2, 7, 7) 64 | out = self.batchNorm1(out) 65 | out = F.leaky_relu(out, 0.2, True) 66 | out = self.conv3(out) # (batch, TRANS_CONV_SIZE*2, 7, 7)->(batch, TRANS_CONV_SIZE*4, 3, 3) 67 | out = self.batchNorm2(out) 68 | out = F.leaky_relu(out, 0.2, True) 69 | out = self.conv4(out) # (batch, TRANS_CONV_SIZE*4, 3, 3)->(batch, 1, 1, 1) 70 | out = torch.sigmoid(out) 71 | return out 72 | 73 | def initWeight(m): 74 | classname = m.__class__.__name__ 75 | if classname.find('Conv') != -1: 76 | nn.init.normal_(m.weight.data, 0.0, 0.02) 77 | elif classname.find('BatchNorm') != -1: 78 | nn.init.normal_(m.weight.data, 1.0, 0.02) 79 | nn.init.constant_(m.bias.data, 0) 80 | 81 | def train(generator_model, discriminator_model, device, train_loader, generator_optimizer, discriminator_optimizer, epoch, gLossList, dLossList, realScoreList, fakeScoreList1, fakeScoreList2): 82 | ''' 83 | 训练函数 84 | ''' 85 | generator_model.train() 86 | discriminator_model.train() 87 | gLossSum = 0 88 | dLossSum = 0 89 | realScoreSum = 0 90 | fakeScore1Sum = 0 91 | fakeScore2Sum = 0 92 | iters = 0 93 | for batch_idx, (data,_) in enumerate(train_loader): 94 | # 更新判别器参数 95 | # discriminator_model.zero_grad() 96 | discriminator_optimizer.zero_grad() 97 | # 计算真实图片的loss 98 | data = data.to(device) 99 | # 生成数据标签,真实label=1 100 | dataNum = data.size(0) 101 | realLabel = torch.ones(dataNum).to(device) 102 | # 将真实数据输入判别器 103 | realOutput = discriminator_model(data).view(-1) 104 | realLoss = F.binary_cross_entropy(realOutput, realLabel) 105 | realScore = realOutput.mean().item() 106 | # 计算伪造图片的loss 107 | # 生成随机噪声 108 | noise = torch.randn(dataNum, INT_DIMENSION,1,1).to(device) 109 | # 获得虚假图片 110 | fakeData = generator_model(noise) 111 | # 生成数据标签,虚假label=0 112 | fakeLabel = torch.zeros(dataNum).to(device) 113 | # 将虚假数据输入判别器 114 | fakeOutput = discriminator_model(fakeData.detach()).view(-1) 115 | fakeLoss = F.binary_cross_entropy(fakeOutput, fakeLabel) 116 | fakeScore1 = fakeOutput.mean().item() 117 | # 计算loss,更新梯度 118 | dLoss = realLoss + fakeLoss 119 | dLoss.backward() 120 | discriminator_optimizer.step() 121 | 122 | # 更新生成器参数 123 | # generator_model.zero_grad() 124 | generator_optimizer.zero_grad() 125 | # 获取生成图片在判别器的输出值 126 | output = discriminator_model(fakeData).view(-1) 127 | # 计算loss,更新梯度 128 | gLoss = F.binary_cross_entropy(output, realLabel) 129 | gLoss.backward() 130 | fakeScore2 = output.mean().item() 131 | generator_optimizer.step() 132 | 133 | # 输出结果 134 | if (batch_idx+1)%50==0: 135 | print('[{}/{}][{}/{}]\tLoss_D: {:.4f}\tLoss_G: {:.4f}\tD(x): {:.4f}\tD(G(z)): {:.4f}/{:.4f}'.format( 136 | epoch, EPOCHS, batch_idx+1, len(train_loader), 137 | dLoss.item(), gLoss.item(), realScore, fakeScore1, fakeScore2)) 138 | gLossSum += gLoss.item() 139 | dLossSum += dLoss.item() 140 | realScoreSum += realScore 141 | fakeScore1Sum += fakeScore1 142 | fakeScore2Sum += fakeScore2 143 | iters += 1 144 | gLossList.append(gLossSum/iters) 145 | dLossList.append(dLossSum/iters) 146 | realScoreList.append(realScoreSum/iters) 147 | fakeScoreList1.append(fakeScore1Sum/iters) 148 | fakeScoreList2.append(fakeScore2Sum/iters) 149 | 150 | def test(generator_model, discriminator_model, device, test_loader, gLossList, dLossList, realScoreList, fakeScoreList): 151 | ''' 152 | 训练函数 153 | ''' 154 | generator_model.train() 155 | discriminator_model.train() 156 | gLossSum = 0 157 | dLossSum = 0 158 | fakeScoreSum = 0 159 | realScoreSum = 0 160 | iters = 0 161 | with torch.no_grad(): 162 | for (data,_) in test_loader: 163 | # 计算真实图片的loss 164 | data = data.to(device) 165 | # 生成数据标签,真实label=1 166 | dataNum = data.size(0) 167 | realLabel = torch.ones(dataNum).to(device) 168 | # 将真实数据输入判别器 169 | realOutput = discriminator_model(data).view(-1) 170 | realLoss = F.binary_cross_entropy(realOutput, realLabel) 171 | realScore = realOutput.mean().item() 172 | # 计算伪造图片的loss 173 | # 生成随机噪声 174 | noise = torch.randn(dataNum, INT_DIMENSION,1,1).to(device) 175 | # 获得虚假图片 176 | fakeData = generator_model(noise) 177 | # 生成数据标签,虚假label=0 178 | fakeLabel = torch.zeros(dataNum).to(device) 179 | # 将虚假数据输入判别器 180 | fakeOutput = discriminator_model(fakeData).view(-1) 181 | fakeLoss = F.binary_cross_entropy(fakeOutput, fakeLabel) 182 | fakeScore = fakeOutput.mean().item() 183 | # 计算loss,更新梯度 184 | dLoss = realLoss + fakeLoss 185 | gLoss = F.binary_cross_entropy(fakeOutput, realLabel) 186 | # 输出结果 187 | gLossSum += gLoss.item() 188 | dLossSum += dLoss.item() 189 | fakeScoreSum += fakeScore 190 | realScoreSum += realScore 191 | iters += 1 192 | gLossList.append(gLossSum/iters) 193 | dLossList.append(dLossSum/iters) 194 | fakeScoreList.append(fakeScoreSum/iters) 195 | realScoreList.append(realScoreSum/iters) 196 | print('test\tLoss_D: {:.4f}\tLoss_G: {:.4f}\tD(x): {:.4f}\tD(G(z)): {:.4f}'.format( 197 | dLossList[-1], gLossList[-1], realScoreList[-1], fakeScoreList[-1])) 198 | 199 | def generate(generator_model, noise): 200 | with torch.no_grad(): 201 | fakeImg = generator_model(noise).cpu() 202 | return utils.make_grid(fakeImg, padding=2, normalize=True) 203 | 204 | def fit(generator_model, discriminator_model, generator_optimizer, discriminator_optimizer, trainLoader, testLoader, fixedNoise): 205 | train_gLossList = list() 206 | train_dLossList = list() 207 | train_realScoreList = list() 208 | train_fakeScoreList1 = list() 209 | train_fakeScoreList2 = list() 210 | test_gLossList = list() 211 | test_dLossList = list() 212 | test_realScoreList = list() 213 | test_fakeScoreList = list() 214 | imgList = list() 215 | for epoch in range(1, EPOCHS + 1): 216 | train(generator_model, discriminator_model, DEVICE, 217 | trainLoader, generator_optimizer, discriminator_optimizer, 218 | epoch, train_gLossList, train_dLossList, train_realScoreList, 219 | train_fakeScoreList1, train_fakeScoreList2) 220 | test(generator_model, discriminator_model, DEVICE, 221 | testLoader, test_gLossList, test_dLossList, test_realScoreList, 222 | test_fakeScoreList) 223 | imgList.append(generate(generator_model, fixedNoise)) 224 | return (train_gLossList,train_dLossList,train_realScoreList, 225 | train_fakeScoreList1,train_fakeScoreList2, 226 | test_gLossList,test_dLossList, 227 | test_realScoreList,test_fakeScoreList,imgList 228 | ) 229 | 230 | def main(): 231 | # 加载数据 232 | dataTransform = transforms.Compose([ 233 | transforms.ToTensor(), 234 | transforms.Normalize((0.5,),(0.5,)) 235 | ]) 236 | trainDatasets = datasets.MNIST(root='./data', train=True, download=True, 237 | transform=dataTransform) 238 | testDatasets = datasets.MNIST(root='./data', train=False, download=True, 239 | transform=dataTransform) 240 | trainLoader = DataLoader(trainDatasets, batch_size=BATCH_SIZE, shuffle=True) 241 | testLoader = DataLoader(testDatasets, batch_size=BATCH_SIZE, shuffle=True) 242 | # 查看真实图像 243 | plt.figure() 244 | realData = next(iter(trainLoader)) 245 | plt.axis("off") 246 | plt.title("Real Images") 247 | plt.imshow(np.transpose(utils.make_grid(realData[0].to(DEVICE)[:64], padding=2, normalize=True).cpu(),(1,2,0))) 248 | plt.savefig("output/real_images.png", dpi=400) 249 | plt.show() 250 | # 设置随机种子 251 | manualSeed = 999 252 | random.seed(manualSeed) 253 | torch.manual_seed(manualSeed) 254 | # 加载模型和优化器 255 | generator = Generator().to(DEVICE) 256 | generator.apply(initWeight) 257 | summary(generator, input_size=(INT_DIMENSION,1,1)) 258 | generatorOptimizer = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5,0.999)) 259 | 260 | discriminator = Discriminator().to(DEVICE) 261 | discriminator.apply(initWeight) 262 | summary(discriminator, input_size=(CHANNEL_NUM,28,28)) 263 | discriminatorOptimizer = optim.Adam(discriminator.parameters(),lr=0.0002, betas=(0.5,0.999)) 264 | # 训练拟合 265 | fixedNoise = torch.randn(64, INT_DIMENSION, 1, 1, device=DEVICE)# 固定噪声 266 | (train_gLossList,train_dLossList,train_realScoreList, 267 | train_fakeScoreList1,train_fakeScoreList2, 268 | test_gLossList,test_dLossList, 269 | test_realScoreList,test_fakeScoreList,imgList 270 | ) = fit(generator, discriminator, generatorOptimizer, discriminatorOptimizer, trainLoader, testLoader, fixedNoise) 271 | # 生成曲线图 272 | plt.figure() 273 | plt.xlabel("Epochs") 274 | plt.ylabel("Loss") 275 | plt.plot(range(EPOCHS), train_gLossList, label="generator train") 276 | plt.plot(range(EPOCHS), train_dLossList, label="discriminator train") 277 | plt.plot(range(EPOCHS), test_gLossList, label="generator test") 278 | plt.plot(range(EPOCHS), test_dLossList, label="discriminator test") 279 | plt.legend() 280 | plt.grid() 281 | plt.savefig("output/loss.png", dpi=400) 282 | plt.show() 283 | plt.figure() 284 | plt.xlabel("Epochs") 285 | plt.ylabel("Loss") 286 | plt.plot(range(EPOCHS), train_realScoreList, label="D(x) train") 287 | plt.plot(range(EPOCHS), train_fakeScoreList1, label="D1(G(z)) train") 288 | plt.plot(range(EPOCHS), train_fakeScoreList2, label="D2(G(z)) train") 289 | plt.plot(range(EPOCHS), test_realScoreList, label="D(x) test") 290 | plt.plot(range(EPOCHS), test_fakeScoreList, label="D(G(z)) test") 291 | plt.legend() 292 | plt.grid() 293 | plt.savefig("output/score.png", dpi=400) 294 | plt.show() 295 | # 比较真实图片和生成图片 296 | plt.figure() 297 | plt.subplot(1,2,1) 298 | plt.axis("off") 299 | plt.title("Real Images") 300 | plt.imshow(np.transpose(utils.make_grid(realData[0].to(DEVICE)[:64], padding=2, normalize=True).cpu(),(1,2,0))) 301 | 302 | plt.subplot(1,2,2) 303 | plt.axis("off") 304 | plt.title("Fake Images") 305 | plt.imshow(np.transpose(generate(generator, fixedNoise),(1,2,0))) 306 | plt.savefig("output/compare.png", dpi=400) 307 | plt.show() 308 | #将图片写入writer,生成gif 309 | with imageio.get_writer("output/output.gif", mode='I') as writer: 310 | for i in range(0,len(imgList)): 311 | writer.append_data(np.transpose(imgList[i],(1,2,0)).numpy()) 312 | 313 | if __name__=='__main__': 314 | main() -------------------------------------------------------------------------------- /18308013-陈家豪-assignment5/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/18308013-陈家豪-assignment5/report.pdf -------------------------------------------------------------------------------- /18308013-陈家豪-assignment5/results/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/18308013-陈家豪-assignment5/results/output.gif -------------------------------------------------------------------------------- /18308013-陈家豪-assignment5/results/output2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/18308013-陈家豪-assignment5/results/output2.gif -------------------------------------------------------------------------------- /Assignment 1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/Assignment 1.pdf -------------------------------------------------------------------------------- /Assignment 2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/Assignment 2.pdf -------------------------------------------------------------------------------- /Assignment 3-期中.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/Assignment 3-期中.pdf -------------------------------------------------------------------------------- /Assignment 4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/Assignment 4.pdf -------------------------------------------------------------------------------- /Assignment 5-期末.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnhaox/2021Spring-SYSU-Machine_Learning_and_Data_Mining/c5a2cc924c9375cc1d8cfa64a625c0f13d882f45/Assignment 5-期末.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2021Spring-SYSU-Machine_Learning_and_Data_Mining 2 | 3 | ## 1 Introduction 4 | There is my homework set. This undergraduate course is "Machine Learning and Data Mining" of the School of Computer Science, Sun Yat-Sen University in the spring of 2021. The instructor is Qinliang Su. 5 | 6 | 这是我在上中带计院的《机器学习与数据挖掘》本科课程时完成的课程作业与实验项目,老师为苏勤亮。内容只是简单备份,仅供参考。 7 | 8 | ## 2 Contents 9 | ### 2.1 Assignment 1 10 | 分别考虑交叉熵损失和均方误差损失,自己实现一个10类的线性分类器。 11 | 12 | ### 2.2 Assignment 2 13 | 调包实现一个使用不同核函数的SVM二分类器,并与采用不同loss的线性分类模型进行性能比较。 14 | 15 | ### 2.3 Assignment 3-期中 16 | 学习一种深度学习框架,探索神经网络在图像分类任务上的应用。 17 | 18 | ### 2.4 Assignment 4 19 | 以MNIST 数据集为例,探索K-Means 和GMM这两种聚类算法的性能。 20 | 21 | ### 2.5 Assignment 5-期末 22 | 自由发挥,~~越卷越好~~。 23 | 24 | 由于那段时间在忙着夏令营、没时间卷,于是就草草地做了个深度生成模型,使用DCGAN生成MNIST和CIFAR10的图像。 25 | 做完后自我感觉良好,还把结果放在夏令营面试时的PPT里面,结果被面试老师吐槽“怎么生成的图片长得不像?”…… 26 | 27 | ~~下面是被面试老师吐槽的结果展示~~ 28 | 29 | ![MNIST生成GIF](https://github.com/cnhaox/2021spring-SYSU-Machine_Learning_And_Data_Mining/blob/master/18308013-%E9%99%88%E5%AE%B6%E8%B1%AA-assignment5/results/output.gif) 30 | 31 | ![CIFAR10生成GIF](https://github.com/cnhaox/2021spring-SYSU-Machine_Learning_And_Data_Mining/blob/master/18308013-%E9%99%88%E5%AE%B6%E8%B1%AA-assignment5/results/output2.gif) 32 | --------------------------------------------------------------------------------