前段时间太浪了,现在就用日志的方式约束自己每天的学习任务,希望有个好的结果~
一、cs231n课程作业部分
cs231n视觉与深度学习课程是很适合补基础的课程,当然也有一定的难度,因为双系统Linux坏了,就打算在windows下配置cs231n的作业环境。
1.使用Anaconda
Anaconda本质上就是一个环境管理器,可以用这一个终端配置电脑的python各种环境,也可以下载各种包,使用了一段时间,我觉得必须要安装的几个包就是pip(下载工具)、jupyter notebook(代码编辑工具)、要使用的python版本以及自建的虚拟环境(包含要使用的所有头文件,例如numpy,script,etc.)。
安装可以在Anaconda Prompt中采用pip install xxx的形式,也可以采用conda安装方式,输入你安装的名称后缀--version可以查看版本和安装信息,总得来说,anaconda对于python开发是非常方便的,集成度高,包的下载也比较省时间(部分包下载巨慢QAQ)
对于新人有一点可能比较重要的就是jupyter的使用,首先我们要将她升级到最新版,然后!很关键的一点就是,不要直接输入jupyter notebook开打开网页,这样在你用notebook去upload其他.ipynb文件后,会出现MoudlenotFounderror,原因就是你的jupyter notebook打开路径不在你的.ipynb文件路径中,找不到所import的文件和函数,对于这个问题,我花了很久的时间在debug上,殊不知原来是路径问题(真蠢!),不过程序这种东西就是这样,bug千奇百怪,找的时候觉得很困难找不到,找到了又觉得也没啥很简单,这就需要大量的debug经验惹。。。打开对应路径的方法是在Anaconda Prompt终端输入:
jupyter notebook URL(e.g.:D:\study\cs231n\CS231n-2017-master\assignment1)
之后就会自动打开jupyter,点开.ipynb文件即可开始作业!
2.knn作业代码分享
根据课程内容,我开始了作业的编写……
首先是...\cs231n\classifiers\k_nearest_neighbor.py
作业中把要求写的地方都空出来了并做了要求,第一部分是要每个测试数据和每个训练数据分别计算(两层循环),并且不可以使用loop。
L2 distance:dists[i,j] = np.sqrt(np.sum((X[i,:]-self.X_train[j,:])**2))
第二部分是每个测试数据和训练数据分别整体进行计算(一层循环)
dists[i,:] = np.sqrt(np.sum((X[i,:] - self.X_train)**2, axis = 1)),注意axis一定要赋值为1,因为是在一维求距离,X[i,:]维度由于广播的原因会变为num_train*D,因此和X_train[i:]运算后dists[i,:]维度为1*num_train。
第三部分是计算所有的测试点和训练点,无循环
X_squared = np.sum(X**2,axis=1)
Y_squared = np.sum(self.X_train**2,axis=1)
XY = np.dot(X, self.X_train.T)
dists = np.sqrt(X_squared[:,np.newaxis] + Y_squared -2*XY)
第四部分是predict
test_row = dists[i,:]
sorted_row = np.argsort(test_row)
closest_y = self.y_train[sorted_row[0:k]]
np.argsort()
可以对dists[] 进行排序选出test_row个最近的训练样本的下标
closest_y即为找到的最近的k个样本
然后需要在这k个样本中找到最接近的一个,返回到y_pred[]数组
y_pred[i] = np.argmax(np.bincount(closest_y))
第五部分是对代码的测试,根据课程内容在jupyter上完成,报了一些错误,已解决。
knn部分已完成,由于需要把测试集每一张图片和训练集进行L1 L2比对,时间上实属浪费,所以只需要了解原理,不需要深究,明天研究softmax!
二、LeetCode刷题部分
1.第九题:回文数
要求:输入数字,正序倒序一样即为true,否则false
此题较为简单,首先拿到题要分析输入源,输入数字可以是正数和负数还有0,众所周知,个位数正数一定是回文数,那么我们吧0-9这十个数归为一类,负数一定不是回文数,也为一类,那我们要考虑的就是11-无穷,当然不能越int的范围。
此题最简单的方法就是用基本的求余数整除法,但是需要把每一位放入数组,静态数组的方法效率较低,所以可以采用动态数组的方法,也就是我们常用的vector向量,自带push_back函数,方便放入数组(此处就不如python的列表舒服惹。。。),然后头尾进行比较即可判断,当然效率最高的方法还是用链表加指针变量哦。下面贴出代码:
class Solution {
public:
bool isPalindrome(int x) {
if(x<0)
{
return false;
}
if(x>-1&&x<10)
{
return true;
}
vector<int> v;
while(x>0)
{
int num =x%10;
x/=10;
v.push_back(num);
}
int pre=0,last=v.size()-1;
while(pre<=last)
{
if(v[pre]!=v[last])
return false;
pre++;
last--;
}
return true;
}
};
2.第七题:整数反转
此题要求将32位有符号整数进行反转,因为有符号且要考虑到0反转在首位取消的问题,就采用逢十进位的方法,首先保证输入数字不能是越界数,卡一下范围,然后有一个小问题,可能被忽略的比较多,我们平时接触的都是正数整除,而负数整除会有怎样的结果呢?没chuo,都是向零取整,怎么理解呢,比如9/-4 = 1,9/(-4) = -1,5%-3 = 2 ,-5%-3 = -2 ;换句话缩,就是不用考虑那么多,直接当成正数去整除和取余就好啦,结果一样的,该带的负号一个不少,代码如下:
class Solution {
public:
int reverse(int x) {
if(x>2147483647||x<-2147483648)
{
return 0;
}
char num[15]={};
int low_num;
int temp=x;
long result=0;
int i=0;
while(temp!=0)
{
low_num=temp%10;
temp=temp/10;
num[i]=low_num;
result=result*10+num[i++];
if(result>2147483647||result<-2147483648)
{
return 0;
}
}
return result;
}
};
3.第六题:Z字变换
此题要求是。。。懒得打字了,贴图吧
相信这个题读完第一遍就会问,如果是四行五行是啥样呢?
那你就把这个题理解为N变换,一堆NNNNNN连在一起。。。。神奇哦
言归正传,这个题我看完他的怕排布规律之后发现是个周期性的排列,那么我们就可以利用他的周期性来解题,例如三阶的,第一行字母在原字符串排序分别是1 5 9 13,第二行排序是2 4 6 8 10 12……,所以规律很明显,再扩充到四阶,规律就更明显了,利用周期性解题是关键,这个题就变成了找规律问题!
int Time=(numRows-2)+numRows;这个Time即为周期,不同人对周期的算法不同,这里只是个人的计算方式。。。
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1)
{
return s;
}
int Time=(numRows-2)+numRows;
string a="";
for(int i=0;i<numRows;i++)
{
int count=0;
while(1)
{
if(count*Time+i<s.length())
{
a+=s[count*Time+i];
}
else
{
break;
}
if(i==0||i==Time/2)
{
count++;
continue;
}
if(count*Time+Time-i<s.length())
{
a+=s[count*Time+Time-i];
}
else
{
break;
}
count++;
}
}
return a;
}
};
因为涉及到字符串,第一个想法就是遍历,那么遍历就离不开while,所以后面的代码都是卸载whlie中~
上面的代码是定义了一个string类型空字符串,然后进行第一行字符的统计,根据string的用法,我们可以直接在空字符串中添加筛选出来的字符
我们可以看到,不管有多少行,每一行字符的下标规律只有两种,count*Time+i即为第一行字符和最后一行下标的通用公式,每找对一个,则会进入下面的if语句进行count++,这里我用到了continue,是为了不继续进行下面的中间行下标规律语句,而是直接再进行while循环继续找第一行的字符
如果找完了第一行所有元素,那么就会在最开始break,跳出while循环,i++,然后直接进行中间行的字符提取,中间行字符的下标规律为count*Time+Time-i,找完了这一行之后进行count++,进行下一行的筛选。
明天计划:刷2-3个LeetCode题目,cs231n学习softmax
希望能坚持,加油~