第一部分:选择题(50分)
1、10分
在一个0/1 分类任务中:我们训练了一个神经网络,对于每个样本点,其输出为该样本是1类的概率:通常,我们会设置一个threshold, 如果预测的概率大于此值,则分为1类,反之为0类;假设,当threshold=0.5时, 预测结果的precision,recall分别是0.8, 0.8;此时,如果我们把threshold调高到0.6, 将会得到组新的预测结果。请问以下那组选项最有可能是这组新的预测结果的precision和recall?
A.-0.9,0.9
B.-0.9,0.7
C.-0.7,0.9
D.-0.7,0.7
思路:一般而言,p和r是两个矛盾的指标,不能两者都大或者都小,所以首先排除AD,当阈值调高的时候,那么需要有更大的把握,才能判断为正类,那么查准率提高,但是相应的,许多真正的好瓜,就被分为坏瓜了,所以查全率降低。综上所述选B。
2、5分
下面的函数不是凸函数的为:
A.f(z) = max(0,1-z)
B.f(z) = z^3
C.f(z) = exp(-z)
D.f(z) = log(1 + exp(-z))
思路:判断一个函数是否是凸函数,可以利用二阶导数是否非负来判断,那么B的二阶导数是6z,明显不满足条件,所以选B。
3、5分
GoogleNet中的1*1卷积核的作用是()
A.降维
B.减少参数
C.跨通道通信
D.其他三个选项都包括
思路:选D
4、15分
考虑一个0/1二分类模型,模型参数为实数w,b
输入为一个实数X,输出Y的表达式为:
假设我们的训练集中包含N个样本点X[1],X[2],…,X[N](保证没有重合点:X[i]!=X[j] if i !=j),以及每个样本点对应的标签Y[1],Y[2],…,Y[N]。
请问当N最大是多少时,不论训练集中X和Y的取值如何,
我们都可能得到一个模型,其训练误差等于0(训练集上的预测结果完全正确)
A.2
B.3
C.4
D.大于4
5、15分
下面的python3函数,如果输入的参数n非常大,函数的返回值会趋近于以下哪一个值?
A. 1334323 / 1679616
B. 1334324 / 1679616
C. 1334325 / 1679616
D. 1334325 / 1679616
思路:这个题就是在求,第一轮count+1,;第二轮count+1;……,第n轮count+1,的概率之和是多少。
(第一轮)
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,break的概率是:i大于(cur%x 1000000 % 6 = 4)的概率就是1/6(注意0-5是有6个数);
(2)count += 1再break的概率是:4/6
(3)不break,直接cur//x,进入第二轮的概率是1/6
(然后cur = cur //6 = 1000000 // 6 = 166666)
(cur%6 = 166666 % 6 = 4)
(第二轮)
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,如果比4大,就break(这里的概率和第一轮一样是1/6);
(2)count += 1再break的概率是:4/6
(3)不break,直接cur//x,进入第二轮的概率是1/6
第二轮,count += 1再break的概率是1/6*4/6
进入下一轮的概率是1/6 * 1/6
(然后cur = cur //6 = 166666 // 6 = 27777)
(cur % 6 = 27777 %6 =3)
(第三轮)
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,如果比3大,就break,这里的概率是2/6;
(2)count += 1再break的概率是:3/6
(3)不break,直接cur//x的概率是1/6
第三轮,count += 1再break的概率是 1/6 * 1/6 * 3/6
进入下一轮的概率是1/6 * 1/6 * 1/6
(然后cur = cur //6 = 27777 // 6 =4629 )
(cur % 6 = 4629 % 6 =3)
(第四轮)
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,如果比3大,就break,这里的概率是2/6;
(2)count += 1再break的概率是:3/6
(3)不break,直接cur//x的概率是1/6
第四轮,count += 1再break的概率是 1/6 * 1/6 * 1/6 * 3/6
进入下一轮的概率是1/6 * 1/6 * 1/6 * 1/6
(然后cur = cur //6 = 4629 // 6 = 771)
(cur % 6 = 771 %6 =3)
(第五轮)
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,如果比3大,就break,这里的概率是2/6;
(2)count += 1再break的概率是:3/6
(3)不break,直接cur//x的概率是1/6
第五轮,count += 1再break的概率是 1/6 * 1/6 * 1/6 * 1/6 * 3/6
进入下一轮的概率是1/6 * 1/6 * 1/6 * 1/6 * 1/6
(然后cur = cur //6 = 771 // 6 = 128)
(cur %6=128%6=2)
(第六轮)
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,如果比2大,就break,这里的概率是3/6;
(2)count += 1再break的概率是:2/6
(3)不break,直接cur//x的概率是1/6
第六轮,count += 1再break的概率是 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 2/6
进入下一轮的概率是1/6 * 1/6 * 1/6 * 1/6 * 1/6* 1/6
(然后cur = cur // 6 = 128 // 6 = 21)
(cur % 6 = 21 % 6 = 3)
(第七轮)
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,如果比3大,就break,这里的概率是2/6;
(2)count += 1再break的概率是:3/6
(3)不break,直接cur//x的概率是1/6
第七轮,count += 1再break的概率是 1/6 * 1/6 * 1/6 * 1/6 * 1/6* 1/6* 3/6
进入下一轮的概率是1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6
所以 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 3/6
(然后cur = cur //6 = 21 //6 = 3)
(cur % 6 = 3 % 6 = 3 )
(第八轮)
补充知识:在C语言中,%符号表示的是求余运算,在python脚本中,%表示的是取模。
(1)i = random.randint(0,x-1)#i是0到5之间的一个随机数,如果比3大,就break,这里的概率是2/6;
(2)count += 1再break的概率是:3/6
(3)不break,直接cur//x的概率是1/6
第八轮,count += 1再break的概率是 1/6 * 1/6 * 1/6 * 1/6 * 1/6* 1/6* 1/6*1/6*3/6
进入下一轮的概率是1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6*1/6
(cur // 6 = 3 //6 = 0)
(cur % 6 = 0 % 6 = 0)
循环终止
计算:
4/6 +
1/6 * 4/6 +
1/6 * 1/6 * 3/6 +
1/6 * 1/6 * 1/6 * 3/6 +
1/6 * 1/6 * 1/6 * 1/6 * 3/6+
1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 2/6 +
1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 3/6+
1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 3/6
=1334325/1679616
这道题,有好多陷阱,比如,0-5,很容易想成是5个数,容易导致错误。另外关于在C语言中,%符号表示的是求余运算,在python脚本中,%表示的是取模。这些知识都要知道,计算的时候,要格外注意。
二、填空题
1、15分
如果利用计算机进行一项计算任务,其中的子任务T(a)所在的计算机内部模块A的处理时间为整个任务处理时间的40%,现假设模块A的速度提升为原来的10倍,其他不变,则整个计算任务会提速为原来的( )倍。(精确到小数点后三位)
答案:1/0.640=1.563
思路:假设原来的整个任务的时间为1,那么任务T(a)所在的模块A的处理时间为0.4,剩下部分的处理用时为0.6,现在模块A的速度提升为原来的10倍,那么处理时间变为0.04,总时间为0.6+0.04=0.64,即处理速度变为原来的1/0.64倍=1.563
2、15分
假设你训练了一个线性回归模型 y = w1*x1 +w2*x2 +w3*x3 +b
其中X=[x1, x2, x3]为输入,[w1, w2, w3,b]为模型参数
已知当X=[1,2,3]时,模型的输出为1,当X=[-1,1,4]时,模型的输出为2
请问当X=[0.6, 1.8, 3.2]时,模型的输出为( )
答案:1.2
思路:
3、15分
老版微信中的【看一看】有【朋阅读的原创文章】功能,当一位好友阅读某文章后,该文章就会被系统匿名推荐显示在你的微信【看一看】中,如果你尝试逐一删除好友,直到删除好友后该推荐文章即刻消失,就可以断定是TA在看该文章了。
假设有以下条件:
1:你有888位微信好友
2:你有多部手机,每部手机对应一个微信账号,你可以任意分配组合每部手机里面的微信好友(不限数量可重复)
3.一篇推荐的文章最多只被一位好友阅读
请问:现在你被推荐了1篇文章,在不进行【删除添如好友、变更各个手机的好友组合】的前提下,至少需要( )手机才能通过遍览各个手机的文章显示情况就能知道是谁在看这篇文章?
例如:你有888部手机,每部手机只加一位好友,遍览888部手机的文章显示情况就可以找出是谁在看某篇文章。
答案:10
思路:log2(888)=9.几
二分法,444 444,222 222,111 111,56 55, 28 28, 14 14,7 7,4 4,2 2,1 1
4、15分
小刚用C语言实现了一个print_bytes函数,其输入x为一个无符号的32位整型(4个字节),然后将这4个字节依照在内存中的存储地址,由低到高依次输出每个字节对应的数字。(数字之间无分隔符分割,比如4个字节分别为:0x01,0x0a, 0x02, 0x0b,那么对应的输出为:110211)以下为对应的代码:(仅供参考,无需阅读此段代码仅通过之前的题目描述仍然可以解答本题)
已知在某台节序为little-endian的计算机下,调用该函数的输出为:
012345
请问输入参数x可能的最大值是:( )
答案:792325
订正:795141
思路:16进制转10进制:0x01,0x就代表是16进制的意思,没有实意: a代表 18,b代表11,0代表0x00,12为0x0c,34为0x22,5为0x05
所以输入最大为:0x00为0000 0000,0x0c为0000 1100,0x22为 0010 0010,0x05为0000 0101
拼起来:0000 0000 0000 1100 0010 0010 0000 0101=1+2^2+2^9+2^13+2^18+2^19=795141
5、29.5分
MNIST的训练集共包600000张28x28的灰阶图片, 每张图片上面为个手写的0-9的数字,
小明从MNIST数据集中挑选了4张图片(4张图片没有重复),将每张图片切割成4张14x14子图片(分别应左上角,右上角,左下角,右下角),最件得到1张14x14的子图片。
小明不小心将这16张子图的顺序打乱了,你能帮助小明找出一开始的4张图片所对应的数字是什么吗?
我们将提供给你个data.npz文件,其中包含了MNIST训练集中所有图片的像素值和对应的数字标签,以及16张子图的像素值。请你告诉小明开始挑选的4张图片上面的数字是( )?
(请将这4个数字按照从小到大的那序排列后拼接起来作为答案。比如0012)
Hint:
data.npz的读取以及其中的内容,可以参考如下代码和注释:
数据集:
见附件mnist.npz(请下载)
答案:1578
思路:
关于上述代码的一些解释:
(1)为什么增加了一个维度,这个维度就可以用来代替循环了。
画图看一下:
三、问答题(0.5分)
请简述上面的MNIST题目的求解思路:
思路如下:首先将MNIST数据集中(60000张28x28的图片)每张图片分割为4张14x14的子图(分别为左上角,右上角,左下角,右下角),然后与小明的16张14x14的图片进行匹配,若4个角都匹配上,那么就选择出该数字,匹配上就是直接计算L1距离为0的。