gentoo(2017年圣诞买什么送女友最好)
gentoo,2017年圣诞买什么送女友最好?
送女友的你怎么只知道YSL呢,今天带你走进新的世界。
最近很多品牌都发布了圣诞限定系列,是的你没看错圣!诞!新!品!▼
因为都是最新路透图 ,所以不是特别特别清晰,请大家谅解噢。
今年植村秀与马里奥联名推出圣诞系列,让人瞬间跳回童年▼
产品包装都印上了复古又可爱的像素马里奥图案,卸妆油、气垫腮红、妆前乳,一个比一个可爱▼
口红外表也来了个180度转变,一共推出7个色号,包括2支亮光口红和5支哑光口红,颜色看着都比较日常▼
今年新出的细管唇膏也在其中,也换上了花式外壳,只推出两个色号,分别命名为火花和地下冒险▼
不过这系列最重磅的产品就是这个专业化妆箱了 ,酷炫中透露着可爱是怎么回事▼
这么豪华的阵势怕是不买不行哦
爱热闹、不服输的杨树林,每次推出的节日限定都很精彩。七夕系列已经掏空了直男们的钱包▼
今年圣诞是粉色烟花系列,产品有口红、明彩笔、彩妆盘▼
虽然被人吐槽像妊娠纹,但说是这么说,最后还不是要买▼
口红一共有6个色号,正红色、橘色、裸色、玫瑰豆沙色都有。在Nordstrom上已经可以买到了▼
建议选01号正红色、13号橘色,显白不挑皮▼
CPB每年的圣诞系列都十分用力,去年的「黄金年代」系列极具艺术感▼
今年摇身一变成为新生代花鸟大师,这海报一出估计圈了不少贵妇粉▼
整个圣诞套装包括四种礼盒,外盒都饰以大面积的花鸟水彩,看着就让人眩晕地掏出钱包▼
最吸睛的就是这个彩妆套装,里面有新出的大红色迷你口红和睫毛膏,还有一盒腮红眼影彩妆盘,一整套的售价是900软妹币左右▼
五色眼线套装色号都不太日常,但一盒的价格折合人民币才不到500,相当于一支眼线不到100块,算是比较平易近人的了▼
指甲油的配色真的是超级有圣诞气息,黑色瓶盖上的金色印花让人欲罢不能▼
不瞒大家说,我已经开始搜集,各式圣诞美甲素材了……
马卡龙少女拉杜丽真是个积极向上的好女孩,去年推出丑到亲妈都认不出的大腿唇釉那盛况至今仍历历在目▼
今年更是再接再厉,隆重推出黑化版大腿唇釉。乍一看还以为是十元店的山寨安娜苏▼
不仅金靴换黑靴,还纹上扇子纹身,一看就不是什么正经腿,大概200一支,共有6个色号,颜色也是有些一言难尽▼
虽然大腿唇釉值得进击的diss,好在其他单品还是颜值在线的。
个人最期待的就是这款扇形腮红盘,外壳是折扇形,缀着流苏,里面有一块腮红、一块粉饼,三百多就能买到,真是业界良心了▼
花瓣腮红盅越发雍容华贵,白色的外壳上镶嵌了金色浮雕,就问你买不买吧▼
比较新奇的是这次的身体护理套装,里面有一支护手霜以及迷你版的沐浴露和身体霜,圆嘟嘟的红色小瓶子超可爱,售价200+,很适合买来送人▼
Nars去年和Sarah Moon合作,推出的圣诞系列梦幻到了极致▼
今年又和艺术家Man Ray合作,推出口红、腮红等23种圣诞系列产品,外观上不仅多了艺术家签名还加上金色的唇妆图案,浪起来真是一套又一套呢▼
系列中有个腮红+口红的套装,三角形包装很有艺术感▼
王牌色号Orgasm肯定不会,错过这波骚操作▼
目前还没有看到更多产品信息,但本脑残粉已经在敲碗等了▼
英伦香氛世家祖玛珑,早早预告了今年圣诞系列,阵容可谓是超级豪华,色彩比去年活泼得多,满满一桌新品比平安夜晚宴还要精彩▼
重头戏要数这本圣诞日历,色彩缤纷的包装非常好看,里面不仅有香水、身体乳,还有各种迷你香薰,当然价格也不低,2000+是肯定要的▼
今年还会推出3款限定香水,其中黑白金包装的的黑石榴让人特别期待,有种迷之丝芙兰风情▼
粉色瓶子的绿杏红醋栗限定香水,一秒戳中少女心,而且100ml卖不到800块也是蛮划算的▼
橙花款的包装倒是变化不大,经典香水刷层新漆,想买的心情依然是那么亢奋呢▼
除此之外还有很多套装,香薰蜡烛套装、迷你香薰皂套装,身体护理套装等让人眼花缭乱,本蜈蚣精的手都快剁没了!▼
彩妆界黑马CharlotteTilbury,今年也推出了超级豪华的圣诞系列▼
重度口红控一定不能错过这个,LipMasterclass口红套装,里面不仅包括唇线笔、金管口红,新出的哑光唇釉也是赫然在列▼
金管口红换上了限定包装,主题是上海之夜、美国甜心、英国美女,真是盯紧了世界人民的钱包▼
三款颜色都很好看,咬咬牙all in也是可以的▼
貌美的圣诞日历算是今年的重头戏,里面是CT几乎所有明星产品的迷你装。
一次性让你来个大出血,买完这波,怕是要穷到明年开春了吧▼
每年按时推出圣诞限定蜜粉饼,已经成为黛珂家的优良传统,不过每年都会被拿出来作一番比较▼
今年黛珂将在12月推出,「浪漫蝴蝶」蜜粉饼,美好梦幻中透露着一股影楼乡土气▼
不过真·圣诞系列倒是炸到我的少女心,以甜美的婚礼蛋糕为灵感,雪白的包装搭配上大红色的蝴蝶结,心率立马飙到130▼
大蛋糕礼盒是彩妆套装,售价420左右,里面有限定眼影膏、口红、高光腮红等。小礼盒是限定蜜粉套组,售价约320软妹币,内含蜜粉的正装和便携装,价格还是挺平易近人的,冲着白色的包装盒也要买买买不停歇呀。
猫咪与菊花控PAUL&JOE,每次出新品都有些似曾相识,今年推出的圣诞系列却出乎意料的简单,包括猫咪口红、腮红、液体眼影,整套的价格是400左右▼
好好摆拍一下的话超级无敌上镜,也难怪人家一直是网红▼
其中最吸睛的就是这支猫咪唇膏啦,细腻的香槟色唇膏包裹着口红,有润唇的效果,还能涂出渐变感▼
同期发售的还有这款新妆前,里面含有滋润肌肤的橙花水和透明质酸,带有细闪,擦上能为皮肤增加自然的光泽,金色的瓶子隐隐透出一股高级感▼
彩妆圈小透明IPSA,也推出了圣诞新品来刷存在感,只不过这个彩色马赛克外盒,emmmmm我内心毫无波澜甚至还有点想笑▼
不过它家产品还是不错的,里面这款5色粉饼,定妆的同时还能修正肤色,能让皮肤看起来更加自然通透▼
套装中还包括眼线液笔、眼影膏,以及两支唇蜜一支是清透水红色,一支是带细闪的粉色,都是典型的日系少女色▼
整个套的装价格是四五百左右,性价比还是不错的,但是这片让人两眼一黑的马赛克……IPSA,你这样卖月饼都卖不出去▼
以上就是今天的圣诞新品播报,直男们可以开始“剁手跺脚”了 。
南极有那些动物?
南极有:企鹅、海豹、南极狼、南极贼鸥等。
1、企鹅身披黑白分明的大礼服,喙具橙色,脖子底下有一片橙黄色羽毛,向下逐渐变淡,耳朵后部最深,全身色泽协调。主要分布在南极大陆位于南纬66~77°之间的许多地方。通常以大海中的鱼虾和头足类动物为食。
2、海豹主要分布在寒冷的两极海域,南极海豹生活在南极冰源。海豹科成员大体可以分成北方和南方两各类群,二者可分置于海豹亚科和僧海豹亚科,海豹亚科分布基本限于北半球,而僧海豹亚科出了南半球以外,在北半球的南部也能见到。以鱼类为主要食物,也食甲壳类及头足类。
3、南极狼这种犬科的特有种,于1876年绝种(于西福克兰岛),也是历史上已知唯一灭绝的犬科动物之一。为了生存,南极狼在长期的进化过程中变得犬齿尖锐,能很容易的将食物撕开,几乎不用细嚼就能大口吞下;臼齿也已经非常适应切肉和啃骨头的需要。
4、南极磷虾主要集中于南冰洋。它们围绕着极地分布,最高密度是在大西洋区域。南极磷虾是南极洲生态系统的重点物种,并且为鲸鱼、海豹、豹形海豹、海狗、食蟹海豹、鱿鱼、冰鱼、企鹅、信天翁及其他的鸟类提供了重要的食物来源。
5、南极贼鸥是捕猎者,猎物主要包括鱼和磷虾,但也不放过其他机会。贼鸥多在海岛上空飞翔,一般不到海面上活动,有时为追捕食物也会飞到离岸不远的上空与猎物周旋。贼鸥的飞行能力很强,其展翼翱翔的姿势剽悍暴烈,勇猛无比。
如何2小时快速入门MxNet?
一、MXnet的安装及使用
开源地址:https://github.com/dmlc/mxnet
如下是单节点的具体安装和实验流程,参考于官方文档:http://mxnt.ml/en/latest/build.html#building-on-linux
1.1、基本依赖的安装
sudo apt-get update
sudo apt-get install -y build-essential git libblas-dev libopencv-dev
1.2、下载mxnet
git clone --recursive https://github.com/dmlc/mxnet
1.3、安装cuda
详见博客:http://blog.csdn.net/a350203223/article/details/50262535
1.4、编译支持GPU的MXnet
将mxnet/目录里找到mxnet/make/子目录,把该目录下的config.mk复制到mxnet/目录,用文本编辑器打开,找到并修改以下两行:
USE_CUDA = 1
USE_CUDA_PATH = /usr/local/cuda
修改之后,在mxnet/目录下编译
make -j4
1.5、安装Python支持
cd python;
python setup.py install
有些时候需要安装setuptools和numpy(sudo apt-get install python-numpy)。
1.6、运行Mnist手写体识别实例
MNIST手写数字识别,数据集包含6万个手写数字的训练数据集以及1万个测试数据集,每个图片是28x28的灰度图。在mxnet/example/image-classification里可以找到MXnet自带MNIST的识别样例,我们可以先运行一下试试:
cd mxnet/example/image-classification
python train_mnist.py
在第一次运行的时候会自动下载MNIST数据集。
以上的命令是使用默认的参数运行,即使用mlp网络,在cpu上计算。
如果使用lenet网络,在GPU上实现加速,则使用如下命令:
python train_mnist.py --gpus 0 --network lenet
想要搞清楚一个框架怎么使用,第一步就是用它来训练自己的数据,这是个很关键的一步。
二、MXnet数据预处理
整个数据预处理的代码都集成在了toosl/im2rec.py中了,这个首先要造出一个list文件,lst文件有三列,分别是index label 图片路径。如下图所示:
我这个label是瞎填的,所以都是0。另外最新的MXnet上面的im2rec是有问题的,它生成的list所有的index都是0,不过据说这个index没什么用.....但我还是改了一下。把yield生成器换成直接append即可。
执行的命令如下:
sudo python im2rec.py --list=True /home/erya/dhc/result/try /home/erya/dhc/result/ --recursive=True --shuffle=true --train-ratio=0.8
每个参数的意义在代码内部都可以查到,简单说一下这里用到的:--list=True说明这次的目的是make list,后面紧跟的是生成的list的名字的前缀,我这里是加了路径,然后是图片所在文件夹的路径,recursive是是否迭代的进入文件夹读取图片,--train-ratio则表示train和val在数据集中的比例。
执行上面的命令后,会得到三个文件:
然后再执行下面的命令生成最后的rec文件:
sudo python im2rec.py /home/erya/dhc/result/try_val.lst /home/erya/dhc/result --quality=100
以及,sudo python im2rec.py /home/erya/dhc/result/try_train.lst /home/erya/dhc/result --quality=100
来生成相应的lst文件的rec文件,参数意义太简单就不说了..看着就明白,result是我存放图片的目录。
这样最终就完成了数据的预处理,简单的说,就是先生成lst文件,这个其实完全可以自己做,而且后期我做segmentation的时候,label就是图片了..
三、非常简单的小demo
先上代码:
import mxnet as mximport loggingimport numpy as np logger = logging.getLogger() logger.setLevel(logging.DEBUG)#暂时不需要管的logdef ConvFactory(data, num_filter, kernel, stride=(1,1), pad=(0, 0), act_type="relu"): conv = mx.symbol.Convolution(data=data, workspace=256, num_filter=num_filter, kernel=kernel, stride=stride, pad=pad) return conv #我把这个删除到只有一个卷积的操作def DownsampleFactory(data, ch_3x3): # conv 3x3 conv = ConvFactory(data=data, kernel=(3, 3), stride=(2, 2), num_filter=ch_3x3, pad=(1, 1)) # pool pool = mx.symbol.Pooling(data=data, kernel=(3, 3), stride=(2, 2), pool_type='max') # concat concat = mx.symbol.Concat(*[conv, pool]) return concatdef SimpleFactory(data, ch_1x1, ch_3x3): # 1x1 conv1x1 = ConvFactory(data=data, kernel=(1, 1), pad=(0, 0), num_filter=ch_1x1) # 3x3 conv3x3 = ConvFactory(data=data, kernel=(3, 3), pad=(1, 1), num_filter=ch_3x3) #concat concat = mx.symbol.Concat(*[conv1x1, conv3x3]) return concatif __name__ == "__main__": batch_size = 1 train_dataiter = mx.io.ImageRecordIter( shuffle=True, path_imgrec="/home/erya/dhc/result/try_train.rec", rand_crop=True, rand_mirror=True, data_shape=(3,28,28), batch_size=batch_size, preprocess_threads=1)#这里是使用我们之前的创造的数据,简单的说就是要自己写一个iter,然后把相应的参数填进去。 test_dataiter = mx.io.ImageRecordIter( path_imgrec="/home/erya/dhc/result/try_val.rec", rand_crop=False, rand_mirror=False, data_shape=(3,28,28), batch_size=batch_size, round_batch=False, preprocess_threads=1)#同理 data = mx.symbol.Variable(name="data") conv1 = ConvFactory(data=data, kernel=(3,3), pad=(1,1), num_filter=96, act_type="relu") in3a = SimpleFactory(conv1, 32, 32) fc = mx.symbol.FullyConnected(data=in3a, num_hidden=10) softmax = mx.symbol.SoftmaxOutput(name='softmax',data=fc)#上面就是定义了一个巨巨巨简单的结构 # For demo purpose, this model only train 1 epoch # We will use the first GPU to do training num_epoch = 1 model = mx.model.FeedForward(ctx=mx.gpu(), symbol=softmax, num_epoch=num_epoch, learning_rate=0.05, momentum=0.9, wd=0.00001) #将整个model训练的架构定下来了,类似于caffe里面solver所做的事情。# we can add learning rate scheduler to the model# model = mx.model.FeedForward(ctx=mx.gpu(), symbol=softmax, num_epoch=num_epoch,# learning_rate=0.05, momentum=0.9, wd=0.00001,# lr_scheduler=mx.misc.FactorScheduler(2))model.fit(X=train_dataiter, eval_data=test_dataiter, eval_metric="accuracy", batch_end_callback=mx.callback.Speedometer(batch_size))#开跑数据。四、detaiter
MXnet的设计结构是C++做后端运算,python、R等做前端来使用,这样既兼顾了效率,又让使用者方便了很多,完整的使用MXnet训练自己的数据集需要了解几个方面。今天我们先谈一谈Data iterators。
MXnet中的data iterator和python中的迭代器是很相似的, 当其内置方法next被call的时候它每次返回一个 data batch。所谓databatch,就是神经网络的输入和label,一般是(n, c, h, w)的格式的图片输入和(n, h, w)或者标量式样的label。直接上官网上的一个简单的例子来说说吧。
import numpy as npclass SimpleIter: def __init__(self, data_names, data_shapes, data_gen, label_names, label_shapes, label_gen, num_batches=10): self._provide_data = zip(data_names, data_shapes) self._provide_label = zip(label_names, label_shapes) self.num_batches = num_batches self.data_gen = data_gen self.label_gen = label_gen self.cur_batch = 0 def __iter__(self): return self def reset(self): self.cur_batch = 0 def __next__(self): return self.next() @property def provide_data(self): return self._provide_data @property def provide_label(self): return self._provide_label def next(self): if self.cur_batch < self.num_batches: self.cur_batch += 1 data = [mx.nd.array(g(d[1])) for d,g in zip(self._provide_data, self.data_gen)] assert len(data) > 0, "Empty batch data." label = [mx.nd.array(g(d[1])) for d,g in zip(self._provide_label, self.label_gen)] assert len(label) > 0, "Empty batch label." return SimpleBatch(data, label) else: raise StopIteration上面的代码是最简单的一个dataiter了,没有对数据的预处理,甚至于没有自己去读取数据,但是基本的意思是到了,一个dataiter必须要实现上面的几个方法,provide_data返回的格式是(dataname, batchsize, channel, width, height), provide_label返回的格式是(label_name, batchsize, width, height),reset()的目的是在每个epoch后打乱读取图片的顺序,这样随机采样的话训练效果会好一点,一般情况下是用shuffle你的lst(上篇用来读取图片的lst)实现的,next()的方法就很显然了,用来返回你的databatch,如果出现问题...记得raise stopIteration,这里或许用try更好吧...需要注意的是,databatch返回的数据类型是mx.nd.ndarry。
下面是我最近做segmentation的时候用的一个稍微复杂的dataiter,多了预处理和shuffle等步骤:
# pylint: skip-fileimport randomimport cv2import mxnet as mximport numpy as npimport osfrom mxnet.io import DataIter, DataBatchclass FileIter(DataIter): #一般都是继承DataIter """FileIter object in fcn-xs example. Taking a file list file to get dataiter. in this example, we use the whole image training for fcn-xs, that is to say we do not need resize/crop the image to the same size, so the batch_size is set to 1 here Parameters ---------- root_dir : string the root dir of image/label lie in flist_name : string the list file of iamge and label, every line owns the form: index \t image_data_path \t image_label_path cut_off_size : int if the maximal size of one image is larger than cut_off_size, then it will crop the image with the minimal size of that image data_name : string the data name used in symbol data(default data name) label_name : string the label name used in symbol softmax_label(default label name) """ def __init__(self, root_dir, flist_name, rgb_mean=(117, 117, 117), data_name="data", label_name="softmax_label", p=None): super(FileIter, self).__init__() self.fac = p.fac #这里的P是自己定义的config self.root_dir = root_dir self.flist_name = os.path.join(self.root_dir, flist_name) self.mean = np.array(rgb_mean) # (R, G, B) self.data_name = data_name self.label_name = label_name self.batch_size = p.batch_size self.random_crop = p.random_crop self.random_flip = p.random_flip self.random_color = p.random_color self.random_scale = p.random_scale self.output_size = p.output_size self.color_aug_range = p.color_aug_range self.use_rnn = p.use_rnn self.num_hidden = p.num_hidden if self.use_rnn: self.init_h_name = 'init_h' self.init_h = mx.nd.zeros((self.batch_size, self.num_hidden)) self.cursor = -1 self.data = mx.nd.zeros((self.batch_size, 3, self.output_size[0], self.output_size[1])) self.label = mx.nd.zeros((self.batch_size, self.output_size[0] / self.fac, self.output_size[1] / self.fac)) self.data_list = [] self.label_list = [] self.order = [] self.dict = {} lines = file(self.flist_name).read().splitlines() cnt = 0 for line in lines: #读取lst,为后面读取图片做好准备 _, data_img_name, label_img_name = line.strip('\n').split("\t") self.data_list.append(data_img_name) self.label_list.append(label_img_name) self.order.append(cnt) cnt += 1 self.num_data = cnt self._shuffle() def _shuffle(self): random.shuffle(self.order) def _read_img(self, img_name, label_name): # 这个是在服务器上跑的时候,因为数据集很小,而且经常被同事卡IO,所以我就把数据全部放进了内存 if os.path.join(self.root_dir, img_name) in self.dict: img = self.dict[os.path.join(self.root_dir, img_name)] else: img = cv2.imread(os.path.join(self.root_dir, img_name)) self.dict[os.path.join(self.root_dir, img_name)] = img if os.path.join(self.root_dir, label_name) in self.dict: label = self.dict[os.path.join(self.root_dir, label_name)] else: label = cv2.imread(os.path.join(self.root_dir, label_name),0) self.dict[os.path.join(self.root_dir, label_name)] = label # 下面是读取图片后的一系统预处理工作 if self.random_flip: flip = random.randint(0, 1) if flip == 1: img = cv2.flip(img, 1) label = cv2.flip(label, 1) # scale jittering scale = random.uniform(self.random_scale[0], self.random_scale[1]) new_width = int(img.shape[1] * scale) # 680 new_height = int(img.shape[0] * scale) # new_width * img.size[1] / img.size[0] img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_NEAREST) label = cv2.resize(label, (new_width, new_height), interpolation=cv2.INTER_NEAREST) #img = cv2.resize(img, (900,450), interpolation=cv2.INTER_NEAREST) #label = cv2.resize(label, (900, 450), interpolation=cv2.INTER_NEAREST) if self.random_crop: start_w = np.random.randint(0, img.shape[1] - self.output_size[1] + 1) start_h = np.random.randint(0, img.shape[0] - self.output_size[0] + 1) img = img[start_h : start_h + self.output_size[0], start_w : start_w + self.output_size[1], :] label = label[start_h : start_h + self.output_size[0], start_w : start_w + self.output_size[1]] if self.random_color: img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hue = random.uniform(-self.color_aug_range[0], self.color_aug_range[0]) sat = random.uniform(-self.color_aug_range[1], self.color_aug_range[1]) val = random.uniform(-self.color_aug_range[2], self.color_aug_range[2]) img = np.array(img, dtype=np.float32) img[..., 0] += hue img[..., 1] += sat img[..., 2] += val img[..., 0] = np.clip(img[..., 0], 0, 255) img[..., 1] = np.clip(img[..., 1], 0, 255) img[..., 2] = np.clip(img[..., 2], 0, 255) img = cv2.cvtColor(img.astype('uint8'), cv2.COLOR_HSV2BGR) is_rgb = True #cv2.imshow('main', img) #cv2.waitKey() #cv2.imshow('maain', label) #cv2.waitKey() img = np.array(img, dtype=np.float32) # (h, w, c) reshaped_mean = self.mean.reshape(1, 1, 3) img = img - reshaped_mean img[:, :, :] = img[:, :, [2, 1, 0]] img = img.transpose(2, 0, 1) # img = np.expand_dims(img, axis=0) # (1, c, h, w) label_zoomed = cv2.resize(label, None, fx = 1.0 / self.fac, fy = 1.0 / self.fac) label_zoomed = label_zoomed.astype('uint8') return (img, label_zoomed) @property def provide_data(self): """The name and shape of data provided by this iterator""" if self.use_rnn: return [(self.data_name, (self.batch_size, 3, self.output_size[0], self.output_size[1])), (self.init_h_name, (self.batch_size, self.num_hidden))] else: return [(self.data_name, (self.batch_size, 3, self.output_size[0], self.output_size[1]))] @property def provide_label(self): """The name and shape of label provided by this iterator""" return [(self.label_name, (self.batch_size, self.output_size[0] / self.fac, self.output_size[1] / self.fac))] def get_batch_size(self): return self.batch_size def reset(self): self.cursor = -self.batch_size self._shuffle() def iter_next(self): self.cursor += self.batch_size return self.cursor < self.num_data def _getpad(self): if self.cursor + self.batch_size > self.num_data: return self.cursor + self.batch_size - self.num_data else: return 0 def _getdata(self): """Load data from underlying arrays, internal use only""" assert(self.cursor < self.num_data), "DataIter needs reset." data = np.zeros((self.batch_size, 3, self.output_size[0], self.output_size[1])) label = np.zeros((self.batch_size, self.output_size[0] / self.fac, self.output_size[1] / self.fac)) if self.cursor + self.batch_size <= self.num_data: for i in range(self.batch_size): idx = self.order[self.cursor + i] data_, label_ = self._read_img(self.data_list[idx], self.label_list[idx]) data[i] = data_ label[i] = label_ else: for i in range(self.num_data - self.cursor): idx = self.order[self.cursor + i] data_, label_ = self._read_img(self.data_list[idx], self.label_list[idx]) data[i] = data_ label[i] = label_ pad = self.batch_size - self.num_data + self.cursor #for i in pad: for i in range(pad): idx = self.order[i] data_, label_ = self._read_img(self.data_list[idx], self.label_list[idx]) data[i + self.num_data - self.cursor] = data_ label[i + self.num_data - self.cursor] = label_ return mx.nd.array(data), mx.nd.array(label) def next(self): """return one dict which contains "data" and "label" """ if self.iter_next(): data, label = self._getdata() data = [data, self.init_h] if self.use_rnn else [data] label = [label] return DataBatch(data=data, label=label, pad=self._getpad(), index=None, provide_data=self.provide_data, provide_label=self.provide_label) else: raise StopIteration到这里基本上正常的训练我们就可以开始了,但是当你有了很多新的想法的时候,你又会遇到新的问题...比如:multi input/output怎么办?
其实也很简单,只需要修改几个地方:
1、provide_label和provide_data,注意到之前我们的return都是一个list,所以之间在里面添加和之前一样的格式就行了。
2. next() 如果你需要传 data和depth两个输入,只需要传 input = sum([[data],[depth],[]])到databatch的data就行了,label也同理。
值得一提的时候,MXnet的multi loss实现起来需要在写network的symbol的时候注意一点,假设你有softmax_loss和regression_loss。那么只要在最后return mx.symbol.Group([softmax_loss, regression_loss])。
我们在MXnet中定义好symbol、写好dataiter并且准备好data之后,就可以开开心的去训练了。一般训练一个网络有两种常用的策略,基于model的和基于module的。接下来谈一谈他们的使用。
五、Model
按照老规矩,直接从官方文档里面拿出来的代码看一下:
# configure a two layer neuralnetwork data = mx.symbol.Variable('data') fc1 = mx.symbol.FullyConnected(data, name='fc1', num_hidden=128) act1 = mx.symbol.Activation(fc1, name='relu1', act_type='relu') fc2 = mx.symbol.FullyConnected(act1, name='fc2', num_hidden=64) softmax = mx.symbol.SoftmaxOutput(fc2, name='sm')# create a model using sklearn-style two-step way#创建一个model model = mx.model.FeedForward( softmax, num_epoch=num_epoch, learning_rate=0.01)#开始训练 model.fit(X=data_set)具体的API参照http://mxnet.io/api/python/model.html。
然后呢,model这部分就说完了。。。之所以这么快主要有两个原因:
1.确实东西不多,一般都是查一查文档就可以了。
2.model的可定制性不强,一般我们是很少使用的,常用的还是module。
六、Module
Module真的是一个很棒的东西,虽然深入了解后,你会觉得“哇,好厉害,但是感觉没什么鸟用呢”这种想法。。实际上我就有过,现在回想起来,从代码的设计和使用的角度来讲,Module确实是一个非常好的东西,它可以为我们的网络计算提高了中级、高级的接口,这样一来,就可以有很多的个性化配置让我们自己来做了。
Module有四种状态:
1.初始化状态,就是显存还没有被分配,基本上啥都没做的状态。
2.binded,在把data和label的shape传到Bind函数里并且执行之后,显存就分配好了,可以准备好计算能力。
3.参数初始化。就是初始化参数
3.Optimizer installed 。就是传入SGD,Adam这种optimuzer中去进行训练
先上一个简单的代码:
import mxnet as mx # construct a simple MLP data = mx.symbol.Variable('data') fc1 = mx.symbol.FullyConnected(data, name='fc1', num_hidden=128) act1 = mx.symbol.Activation(fc1, name='relu1', act_type="relu") fc2 = mx.symbol.FullyConnected(act1, name = 'fc2', num_hidden = 64) act2 = mx.symbol.Activation(fc2, name='relu2', act_type="relu") fc3 = mx.symbol.FullyConnected(act2, name='fc3', num_hidden=10) out = mx.symbol.SoftmaxOutput(fc3, name = 'softmax') # construct the module mod = mx.mod.Module(out) mod.bind(data_shapes=train_dataiter.provide_data, label_shapes=train_dataiter.provide_label) mod.init_params() mod.fit(train_dataiter, eval_data=eval_dataiter, optimizer_params={'learning_rate':0.01, 'momentum': 0.9}, num_epoch=n_epoch)分析一下:首先是定义了一个简单的MLP,symbol的名字就叫做out,然后可以直接用mx.mod.Module来创建一个mod。之后mod.bind的操作是在显卡上分配所需的显存,所以我们需要把data_shapehe label_shape传递给他,然后初始化网络的参数,再然后就是mod.fit开始训练了。这里补充一下。fit这个函数我们已经看见两次了,实际上它是一个集成的功能,mod.fit()实际上它内部的核心代码是这样的:
for epoch in range(begin_epoch, num_epoch): tic = time.time() eval_metric.reset() for nbatch, data_batch in enumerate(train_data): if monitor is not None: monitor.tic() self.forward_backward(data_batch) #网络进行一次前向传播和后向传播 self.update() #更新参数 self.update_metric(eval_metric, data_batch.label) #更新metric if monitor is not None: monitor.toc_print() if batch_end_callback is not None: batch_end_params = BatchEndParam(epoch=epoch, nbatch=nbatch, eval_metric=eval_metric, locals=locals()) for callback in _as_list(batch_end_callback): callback(batch_end_params)正是因为module里面我们可以使用很多intermediate的interface,所以可以做出很多改进,举个最简单的例子:如果我们的训练网络是大小可变怎么办? 我们可以实现一个mutumodule,基本上就是,每次data的shape变了的时候,我们就重新bind一下symbol,这样训练就可以照常进行了。
总结:实际上学一个框架的关键还是使用它,要说诀窍的话也就是多看看源码和文档了,我写这些博客的目的,一是为了记录一些东西,二是让后来者少走一些弯路。所以有些东西不会说的很全。。
Firefox支持snap安装格式吗?
支持!
Ubuntu , Arch Linux, Solus, Linux Mint OpenSuSE, Fedora, Debian GNU/Linux 以及 Gentoo Linux 等系统都支持 Snap 格式。Snap 格式还可以应用于和云系统以及各种嵌入式设备。
Linux运维前景怎么样?
自动化、云计算时代,Linux运维非常重要!生活日益互联网化的今天,超高并发、超大量的数据同步越来越多,普通服务器根本无法承受,只有Linux运维才能承担,让平台稳定运行。
这些都是Linux运维人员的功劳!
Linux行业也是一个经验越多越吃香的行业
第一梯度
0. 熟悉常见硬件配置,了解常见硬件体系
1. 会搭建常见服务、理解服务工作原理
2. 精通系统工作原理(到这一步已经很少有人能做到了,能过滤掉 80%)
3. 熟悉多种发行版本,RedHat 系(Fedora , CentOS)、Debian 系(Ubuntu)、Gentoo 系(LFS,Arch)4. 熟练的脚本开发 ,Perl,Python,Shell(三选二,或者都会)、自动化技术。
4. 熟练的脚本开发 ,Perl,Python,Shell(三选二,或者都会)、自动化技术。
第二梯度
5. 集群化的管理思维方式 ,可以通过 Puppet ,脚本等等类似工具配合。
6. 性能的极端优化 ,这个工作必须基于 2 的基础,实际上很少有人能够做到
7. 多种数据库的原理、优化 MySQL,Oracle,MongoDB,Redis,这里面够你消耗掉一半的青春
8. 高可用性以及负载均衡思维方式
第三梯度
9. 与开发人员一起,参与架构设计
达到第三梯度,我才想年薪大概在50w到100w之间。
刚开始想学习入门的话,如果你是零基础,建议你找到一份不错的教程,跟着教程学习,这个过程会很慢,或者到黑马程序员参加培训,学习效率比较高,还有老师给予你指导。
最后分享一套学习教程(想要教程的可以私聊我)