作者归档:Muggle

6月

太懒了,快要一个月什么都没写了。眼看着再不写6月可能就要过来。于是趁着现在没什么事,逼着自己写点东西。其实心里毫无感想,虽然最近有很多事可以写。

深圳我来了

提前两天跟老爸老妈来深圳游玩了一下。先前也没有做什么准备和计划,于是到了深圳几乎就是随便走走看看。游了世界之窗,感觉还不错。但是这两天实在是太热了。在世界之窗快要中暑了都~以至于下午老爸就玩不动了,这不像他的风格。星期天晚上(11号)我们就在酒店附近逛了下,就像福田当地的土著一样,悠闲地散散步。

快乐的时光总是过得很快。这一次深圳之行也是老妈第一次出省,第一次坐地铁。

分别

这天是12号,星期一。其实我本来不想他们送我来到门口的,我觉得影响不好。可是昨天下午老爸玩不动,没有提前带他们过来看看以满足他们的心愿,自己心里有点过意不去。我知道他们很想看看我工作的地方,毕竟听上去确实很高大上(SIAT)。昨晚我跟他们说不要跟我过来,他们说好。我可以听出他们的失落,我也能感觉到老妈在看我。可是我还是不想他们跟我来,原因还是担心被别人看了,影响不好。我原计划我等到快中午的时候,送他们到深圳北站坐车,我再自己转地铁来报道。可是老爸说我要早点出发,他们在酒店呆到快中午的时候再自己去北站。

于是我妥协了,我不舍得了。我说道“要不明早,早点出发,一起去吧~”。因为我不想我走后,他们自己留在酒店等时间。我宁愿他们自己去逛逛,这样我心里也好受些。

写到这里,我渐渐的有了感情了。心中有股滋味~

于是今天早上我们一起退了房,一起前往单位。地铁比想象的快。这两天太热了,我们到了以后,直接坐上三轮黑摩的直奔大门。到了以后,我们没有再停留。我告诉老爸不要错过动车了,问道“懂得坐地铁吧?方向不要弄错了。”我忘了还说了写什么,但是不多就几句而已。

“好的,我们这里自己逛一下”。将要转身走的时候,我看着老妈的眼神。至今忘不了,我和她掌对掌挥了下手。就这样提着包,转头就走了。我没有回头,现在想想我都能哭出来的。直到我走进保安亭后,我才想到要看看他们走了吗,可是被一堵墙堵住了,什么也看不到了。

过后我才想起来我忘了把零钱给他们了。

第一天

这一天我来不及感到离别的悲伤。取而代之的是不知所措和恐惧。到了老板的办公室。老板挺年轻的,和他聊了一下,就去就去办理入职手续了。办完之后,老板说我还没有餐卡,中午就和他吃吧。老板人挺好的~感觉很温和~

下午就比较尴尬了~独自一人从中午12点坐在咖啡厅里等宿舍单下来。在咖啡厅里,听着一些人在谈创业,一些人在聊科研,我感觉到这里平静却又充满的生机。大概坐到3点半左右,我真的不知道要干嘛,不知道接下去要怎么办。于是我想到了师兄。他是我们学校研二师兄,同系,老凌的学生。

他一听说我来了,马上就来找我。坐下来以后,问我东西买好了吗?“没有,那走,我带你去买”。这一瞬间我真的感到一股很强的温暖,我很想哭~路上他说“我见到你就像见到自己家人一样,很激动”。我也很激动。买完以后,为了不影响他的工作,我让他先回去了。走时,留了电话,他说晚上他请我一顿。这天晚上,他请了我院里最贵的食堂,3道菜多到我们两个吃不完。剩了有点多,他说太浪费了,于是硬是挤下肚子。师兄我想嫁给你~

接下去的日子

这周是来的第二周。这两周里的事,我准备下次再说~因为字数已经1300字了。

 

 

 

Socket编程:解决发送与接收数据不全

这个问题是在上个月在做的项目中遇到的问题。项目采用分布式计算,通过网线传输数据。然而却发现用Socket接收和发送数据会出现不全的问题。由于是第一次使用Socket,因此这个问题还是费了点时间去解决。现在把它整理下。


客户端
原来的编程方案:(错误)

//创建套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
serv_addr.sin_family = AF_INET;  //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("169.254.48.205");  //具体的IP地址
serv_addr.sin_port = htons(1234);  //端口
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
//向服务器发送数据
printf("Sending...\n");
write(sock, (char*)conv_ouput, sizeof(float) * 25088);
printf("Send Successful\n");
//关闭套接字
close(sock);

这里有个问题,即是发送端不能保证一次性全部发完数据。因此必须确保发送到能够发全数据。

修改后的编程方案:(正确)

int sock = socket(AF_INET, SOCK_STREAM, 0);
//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
serv_addr.sin_family = AF_INET;  //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("169.254.48.205");  //具体的IP地址
serv_addr.sin_port = htons(1234);  //端口
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
//向服务器发送数据
printf("Sending...\n");
int pos = 0;
while(pos < 25088*sizeof(float))
{
	int send_num = send(sock,(char*)conv_ouput+pos, sizeof(float) * 25088, 0);
	if(send_num<=0)
	{
		break;
		printf("send error\n");
	}
	pos += send_num;
}
printf("send num = %d\n",pos);
printf("Send Successful\n");
//关闭套接字
close(sock);

继续阅读

中科院offer!!!

我从来也没有想到我能去中科院实习。周二我在实习僧上看到中科院在招聘实习,于是抱着试试的态度发了简历,没想到第二天就电话面试,面试还很顺利。也就问我现在在做的项目,最后竟然直接说:”那我给你发offer吧~“。真的是把我高兴坏了~真的是高兴坏了~高兴得我把正在睡午觉的舍友摇醒~跟他分享喜悦。第一时间告诉了老爸,姐姐。这两天渐渐平静下来了。

终于要出远门了!从高考后就一心想着考出省,去外面看看。然而现实是在省内选个一本院校容易,在省外选好学校就有可能上不了。于是大学继续省内读书,其实是市内读书。接着就是考研。也是选择离家一千公里的学校,不过最后也是没成。不过我总是能接受现实,于是又留在了市内读研。

现在终于有机会了。但现在的我,就好像一个在浅水区游惯的人,突然到海里去游泳一样。心里有一种巨大的压力感,是对陌生水域的恐惧。

不过人生就是这样,一步一步的往前迈。

Conda 修改源 快速下载

自言自语:趁着现在在训练网络,在4月的最后一天,发表一篇文章。这篇很早之前就已经整理好了,只是迟迟未发表。最近发现当把神经网络移植到FPGA上时,速度居然没有GPU快。也是大跌眼镜了。本来认为可以拿奖的项目,突然又觉得希望渺茫~但项目做到这个地步,只能硬着头皮继续优化下去。(请忽略)


其实很简单,但是也没网上的教程那么简单。在实际中,仅通过命令行修改,并不一定能完全用修改后的源下载,还需要去修改配置文件。

首先设置命令:

conda config –add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda

config –set show_channel_urls yes

然后:需要修改conda的配置文件。删掉-default选项。

conda info -a 查看.condarc文件位置 修改

修改后,下载速度杠杠的!

参考资料:

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/

OpenCL for CodeBlock

这两个礼拜忙于项目。基于OpenCL的VGG-NET卷积神经网络。整个项目的思想很简单,但落实到具体细节上时,我和我队友折腾得焦头烂额。常常一想一个问题,就不舍得去做其他事。以至于放掉了很多计划中的事,包括very9s.net上发表文章,包括英语阅读。趁着现在,项目又进入一个新的问题,停滞不前时,休息下。发表篇文章。


在CodeBlock上搭建OpenCL环境

大部分在windows下的OpenCL环境都是基于visual studio IDE开发环境。其实现在我也是在Visual Studio 2015下进行OpenCL环境开发的。但是Visual studio对于初学者太过臃肿,且如果你是基于C语言开发的,那么Visual Studio支持并不是很好。所以我尝试过CodeBlock下开发,并且一切顺利。

下载时选择带有mingw包,能省去很多步骤。省得自己在配置编译环境。

创建OpenCL的编译器

C/C++ linking (gcc/g++)
    • In order to compile your OpenCL program you must tell the compiler to use the OpenCL library with the flag: –l OpenCL
    • If the compiler cannot find the OpenCL header files (it should do) you must specify the location of the CL/ folder with the –I (capital “i”) flag
    • If the linker cannot find the OpenCL runtime libraries (it should do) you must specify the location of the lib file with the –L flag
    • Make sure you are using a recent enough version of gcc/g++ – at least v4.7 is required to use the OpenCL C++ API (which needs C++11 support)

继续阅读

C语言指针理解

最近在做OpenCL的项目,做异构计算。在做的过程中让我不得不重新温习下C语言,不得不去深入理解指针的含义。下面几点我列出了我在《Beginning C:From Novice to Professional》(Ivor Horton)书中学到的几点关于C指针的内容。内容很浅显,但过了4年,重新理解这些简单的知识点,有许多新的体会。所谓大道至简,指针的魅力也许就在这些简单的定义,微小的细节当中。

1-指针是存储地址的变量。
2-编译器必须知道指针所指的变量类型。没有这个信息,就不知道如何处理所指向的内存内容。
3-void*类型的指针可以包含任意类型的地址。
4-未初始化的指针是非常危险的,所以应该在声明指针的时候对他进行初始化。例如:

int *pointer = NULL;
表示不指向任何内存的位置。NULL在多个头文件中都包含。例如stdio.h string.h等。NULL也相当于数字0的指针。即
int *pointer = 0;
与上面的初始化等价。
int *pointer = &number;
pointer变量中存储的是number的地址。
*pointer则是存储在number中的值。
*又称取消引用运算符。

5-可以改变指针指向的地址,因此同一个指针也可以改变不同内存空间里的值。
6-指向常量的指针:

const int *pointer = &value;
不能通过指针改变所指向的值。但可以直接对value进行操作。也可以改变指针指向的地址。

7-常量指针:

int *const pointer = &value;
指针存储的地址不能改变。但可以改变指针指向的内容。

8-指向常量的常量指针:

const int *const pointer = &item;
不能改变存储在指针中的地址,不能改变指向的内容。

 


指针与数组

1-指针和数组似乎完全不同,但他们有非常紧密的关系,有时候还可以互换。
2-数组和指针重要的区别:

可以改变指针包含的地址;
不能改变数组名称引用的地址。
(使用数组名称而不带索引值,就等于引用数组的第一个元素的地址)


动态内存分配

1-int *pointer = (int*)malloc(5*sizeof(int));

malloc是一般函数,可为任意类型的数据分配内存。因此这个函数并不知道要分配的内存空间要做什么用,所以返回的是一个void类型指针。因此要将返回的地址做类型转换。(int*)

2-int *pointer = (int*)calloc(5,sizeof(int));

calloc()函数与malloc()函数相比有两个优点:
-它把内存分配为给定大小的数组;
-它初始化了所分配的内存,所有位都是0;

3-释放动态内存:

动态内存,应在不需要改内存时释放他们。堆上分配的内存会在程序结束时自动释放,但是为了避免出现内存泄漏,应在使用完后释放内存,或者退出程序时释放内存。
free(pointer);
同时应避免两次释放相同的内存区域,因为这种情况下,free操作是不确定的,因此结果也是无法预料的。

DeepLearning:Linear Class解释

class Linear(Node):
    """
    Represents a node that performs a linear transform.
    """
    def __init__(self, X, W, b):
        # The base class (Node) constructor. Weights and bias
        # are treated like inbound nodes.
        Node.__init__(self, [X, W, b])

    def forward(self):
        """
        Performs the math behind a linear transform.
        """
        X = self.inbound_nodes[0].value
        W = self.inbound_nodes[1].value
        b = self.inbound_nodes[2].value
        self.value = np.dot(X, W) + b

    def backward(self):
        """
        Calculates the gradient based on the output values.
        """
        # Initialize a partial for each of the inbound_nodes.
        self.gradients = {n: np.zeros_like(n.value) for n in self.inbound_nodes}
        # Cycle through the outputs. The gradient will change depending
        # on each output, so the gradients are summed over all outputs.
        for n in self.outbound_nodes:
            # Get the partial of the cost with respect to this node.
            grad_cost = n.gradients[self]
            # Set the partial of the loss with respect to this node's inputs.
            self.gradients[self.inbound_nodes[0]] += np.dot(grad_cost, self.inbound_nodes[1].value.T)
            # Set the partial of the loss with respect to this node's weights.
            self.gradients[self.inbound_nodes[1]] += np.dot(self.inbound_nodes[0].value.T, grad_cost)
            # Set the partial of the loss with respect to this node's bias.
            self.gradients[self.inbound_nodes[2]] += np.sum(grad_cost, axis=0, keepdims=False)

1. the loss with respect to inputs
self.gradients[self.inbound_nodes[0]] += np.dot(grad_cost, self.inbound_nodes[1].value.T)
Cost对某个Node的导数(gradient)等于Cost对前面节点导数的乘积。

解释一:

np.dot(grad_cost, self.inbound_nodes[1].value.T)

对于Linear节点来说,有三个输入参数,即inputs, weights, bias分别对应着

self.inbound_nodes[0],self.inbound_nodes[1],self.inbound_nodes[2]

So, each node will pass on the cost gradient to its inbound nodes and each node will get the cost gradient from it’s outbound nodes. Then, for each node we’ll need to calculate a gradient that’s the cost gradient times the gradient of that node with respect to its inputs.

于是Linear对inputs的求导就是weights。所以是grad_cost*weights.grad_cost是Linear输出节点传递进来的变化率。

np.dot(self.inbound_nodes[0].value.T, grad_cost)

同理可推对weights的求导为inputs,于是gradient=grad_cost*inputs

np.sum(grad_cost, axis=0, keepdims=False)

而对于bias,Linear对bias求导恒为1.所以gradient=1*grad_cost

解释二:为何是+=

因为每一个节点将误差传递给每一个输出节点。于是在Backpropagation时,要求出每一个节点的误差,就要将每一份传递出去给输出节点的误差加起来。于是用+=。
于是可以理解为什么要for n in self.outbound_nodes: 目的是为了在每一个节点的输出节点里遍历。
If a node has multiple outgoing nodes, you just sum up the gradients from each node.

注意点一:
要区分Backpropagation 和Gradient Descent是两个步骤,我通过Backpropagation找到gradient,于是找到了变化方向。再通过Gradient Descent来最小化误差。

To find the gradient, you just multiply the gradients for all nodes in front of it going backwards from the cost. This is the idea behind backpropagation. The gradients are passed backwards through the network and used with gradient descent to update the weights and biases.

最终目的是:

Backpropagation只求了导数部分。Gradient Descent则是整个过程。

 

解决defaults::qt-5.6.2-vc14_3

使用conda 安装tensorflow的时候,出现了这个问题,这不是第一次的出现了。上一次出现,我选择重新安装miniconda,问题解决了。这次我决定去解决他!

ERROR conda.core.link:_execute_actions(330): An error occurred while installing package ‘defaults::qt-5.6.2-vc14_3’. UnicodeDecodeError(‘utf-8′, b’\xd2\xd1\xb8\xb4\xd6\xc6 1 \xb8\xf6\xce\xc4\xbc\xfe\xa1\xa3\r\n‘, 0, 1, ‘invalid continuation byte’) Attempting to roll back. UnicodeDecodeError(‘utf-8′, b’\xd2\xd1\xb8\xb4\xd6\xc6 1 \xb8\xf6\xce\xc4\xbc\xfe\xa1\xa3\r\n‘, 0, 1, ‘invalid continuation byte’)

ERROR conda.core.link:_execute_actions(319): An error occurred while installing package ‘defaults::qt-5.6.2-vc9_3’

python | 解决defaults::qt-5.6.2-vc14_3

这两篇都是同一种解决方法,但是当我试着他们的方法的时候,却出现了新的问题,即ModuleNotFoundError: No module named ‘chardet’

于是我直接用conda在root环境下安装chardet

conda install chardet
最后一切搞定,连上面两篇文章的添加内容都不需要~

笔记本升级SSD

电脑莫名其妙总是蓝屏!一气之下,买了固态硬盘。好在主板只有SATA2的接口,所以正好可以省点钱,买低配的SSD。但是也要500大洋,心疼。不过念在学校又发了1000大洋,想想这台12年高考毕业时买的古董,也算焕发第三春了。

大概是大二的时候,升级了内存。加了一条4G内存。这是第二春(ಡωಡ)hiahiahia

没什么事做,尝试用手机发表文章,试试效果。除了屏幕小以外,其他都可以接受。

作为小白,为了选购SSD还特意去看了知乎相关回答,涨了不少知识。

【如何选购固态硬盘?】dyoule:https://www.zhihu.com/question/20369676/answer/99405990?utm_source=com.meizu.notepaper&utm_medium=social (分享自知乎网)

Very9s第二年

很高兴坚持留下来。最近比较忙,所以写的比较少。但是素材准备了很多。等过段时间,整理整理,写出来。

最近为了自己的项目,焦头烂额的。亚历山大~~不想多说了,有机会再写吧~


2017.5.20添:

删除放在github上的旧站。为了以后还能怀念她,截了首页的图。

这个主题还是我仿照lofter上的主题自己做的。花了可能有一周的时间。好不舍得。