引自:http://blog.csdn.net/sinat_26917383/article/details/72859145

中文文档:http://keras-cn.readthedocs.io/en/latest/ 
官方文档:https://keras.io/ 
文档主要是以keras2.0。 
.


.

Keras系列:

1、keras系列︱Sequential与Model模型、keras基本结构功能(一) 
2、keras系列︱Application中五款已训练模型、VGG16框架(Sequential式、Model式)解读(二) 
3、keras系列︱图像多分类训练与利用bottleneck features进行微调(三) 
4、keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四) 
5、keras系列︱迁移学习:利用InceptionV3进行fine-tuning及预测、完整案例(五)


一、Application的五款已训练模型 + H5py简述

Kera的应用模块Application提供了带有预训练权重的Keras模型,这些模型可以用来进行预测、特征提取和finetune。 
后续还有对以下几个模型的参数介绍:

  • Xception
  • VGG16
  • VGG19
  • ResNet50
  • InceptionV3

所有的这些模型(除了Xception)都兼容Theano和Tensorflow,并会自动基于~/.keras/keras.json的Keras的图像维度进行自动设置。例如,如果你设置data_format=”channel_last”,则加载的模型将按照TensorFlow的维度顺序来构造,即“Width-Height-Depth”的顺序。

模型的官方下载路径:https://github.com/fchollet/deep-learning-models/releases

其中: 
.

1、thtf的区别

==================

Keras提供了两套后端,Theano和Tensorflow, 
th和tf的大部分功能都被backend统一包装起来了,但二者还是存在不小的冲突,有时候你需要特别注意Keras是运行在哪种后端之上,它们的主要冲突有:

dim_ordering,也就是维度顺序。比方说一张224*224的彩色图片,theano的维度顺序是(3,224,224),即通道维在前。而tf的维度顺序是(224,224,3),即通道维在后。 
卷积层权重的shape:从无到有训练一个网络,不会有任何问题。但是如果你想把一个th训练出来的卷积层权重载入风格为tf的卷积层……说多了都是泪。我一直觉得这个是个bug,数据的dim_ordering有问题就罢了,为啥卷积层权重的shape还需要变换咧?我迟早要提个PR把这个bug修掉! 
然后是卷积层kernel的翻转不翻转问题,这个我们说过很多次了,就不再多提。 
数据格式的区别,channels_last”对应原本的“tf”,“channels_first”对应原本的“th”。 
以128x128的RGB图像为例,“channels_first”应将数据组织为(3,128,128),而“channels_last”应将数据组织为(128,128,3)。 
譬如: 
vgg16_weights_th_dim_ordering_th_kernels_notop.h5 
vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5 
.

2、notop模型是指什么?

==============

是否包含最后的3个全连接层(whether to include the 3 fully-connected layers at the top of the network)。用来做fine-tuning专用,专门开源了这类模型。 
.

3、H5py简述

========

keras的已训练模型是H5PY格式的,不是caffe的.caffemodel 
h5py.File类似Python的词典对象,因此我们可以查看所有的键值: 
读入

file=h5py.File('.../notop.h5','r')
f.attrs['nb_layers'],代表f的属性,其中有一个属性为'nb_layers'
>>> f.keys()
[u'block1_conv1', u'block1_conv2', u'block1_pool', u'block2_conv1', u'block2_conv2', u'block2_pool', u'block3_conv1', u'block3_conv2', u'block3_conv3', u'block3_pool', u'block4_conv1', u'block4_conv2', u'block4_conv3', u'block4_pool', u'block5_conv1', u'block5_conv2', u'block5_conv3', u'block5_pool']

可以看到f中各个层内有些什么。

for name in f:
print(name)
# 类似f.keys()

.

4、官方案例——利用ResNet50网络进行ImageNet分类

================================

rom keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input, decode_predictions
import numpy as np model = ResNet50(weights='imagenet') img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x) preds = model.predict(x)
print('Predicted:', decode_predictions(preds, top=3)[0])
# Predicted: [(u'n02504013', u'Indian_elephant', 0.82658225), (u'n01871265', u'tusker', 0.1122357), (u'n02504458', u'African_elephant', 0.061040461)]

还有的案例可见Keras官方文档

利用VGG16提取特征、从VGG19的任意中间层中抽取特征、在定制的输入tensor上构建InceptionV3

.

5、调用参数解释

========

以下几类,因为调用好像都是从网站下载权重,所以可以自己修改一下源码,让其可以读取本地H5文件。

Xception模型

ImageNet上,该模型取得了验证集top1 0.790和top5 0.945的正确率; 
,该模型目前仅能以TensorFlow为后端使用,由于它依赖于”SeparableConvolution”层,目前该模型只支持channels_last的维度顺序(width, height, channels)

默认输入图片大小为299x299

keras.applications.xception.Xception(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None, classes=1000)

VGG16模型

VGG16模型,权重由ImageNet训练而来

该模型再Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序

模型的默认输入尺寸时224x224

keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000)

VGG19模型

VGG19模型,权重由ImageNet训练而来

该模型在Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序

模型的默认输入尺寸时224x224

keras.applications.vgg19.VGG19(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000)

ResNet50模型

50层残差网络模型,权重训练自ImageNet

该模型在Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序

模型的默认输入尺寸时224x224

keras.applications.resnet50.ResNet50(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000)

InceptionV3模型

InceptionV3网络,权重训练自ImageNet

该模型在Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序

模型的默认输入尺寸时299x299

keras.applications.inception_v3.InceptionV3(include_top=True,
weights='imagenet',
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000)

.


二、 keras-applications-VGG16解读——函数式

.py文件来源于:https://github.com/fchollet/deep-learning-models/blob/master/vgg16.py 
VGG16默认的输入数据格式应该是:channels_last

# -*- coding: utf-8 -*-
'''VGG16 model for Keras.
# Reference:
- [Very Deep Convolutional Networks for Large-Scale Image Recognition](https://arxiv.org/abs/1409.1556)
'''
from __future__ import print_function import numpy as np
import warnings from keras.models import Model
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Input
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import GlobalMaxPooling2D
from keras.layers import GlobalAveragePooling2D
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras import backend as K
from keras.applications.imagenet_utils import decode_predictions
# decode_predictions 输出5个最高概率:(类名, 语义概念, 预测概率) decode_predictions(y_pred)
from keras.applications.imagenet_utils import preprocess_input
# 预处理 图像编码服从规定,譬如,RGB,GBR这一类的,preprocess_input(x)
from keras.applications.imagenet_utils import _obtain_input_shape
# 确定适当的输入形状,相当于opencv中的read.img,将图像变为数组
from keras.engine.topology import get_source_inputs WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5' def VGG16(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000):
# 检查weight与分类设置是否正确
if weights not in {'imagenet', None}:
raise ValueError('The `weights` argument should be either '
'`None` (random initialization) or `imagenet` '
'(pre-training on ImageNet).') if weights == 'imagenet' and include_top and classes != 1000:
raise ValueError('If using `weights` as imagenet with `include_top`'
' as true, `classes` should be 1000') # 设置图像尺寸,类似caffe中的transform
# Determine proper input shape
input_shape = _obtain_input_shape(input_shape,
default_size=224,
min_size=48,
# 模型所能接受的最小长宽
data_format=K.image_data_format(),
# 数据的使用格式
include_top=include_top)
#是否通过一个Flatten层再连接到分类器 # 数据简单处理,resize
if input_tensor is None:
img_input = Input(shape=input_shape)
# 这里的Input是keras的格式,可以用于转换
else:
if not K.is_keras_tensor(input_tensor):
img_input = Input(tensor=input_tensor, shape=input_shape)
else:
img_input = input_tensor
# 如果是tensor的数据格式,需要两步走:
# 先判断是否是keras指定的数据类型,is_keras_tensor
# 然后get_source_inputs(input_tensor) # 编写网络结构,prototxt
# Block 1
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x) # Block 2
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x) # Block 3
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x) # Block 4
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x) # Block 5
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) if include_top:
# Classification block
x = Flatten(name='flatten')(x)
x = Dense(4096, activation='relu', name='fc1')(x)
x = Dense(4096, activation='relu', name='fc2')(x)
x = Dense(classes, activation='softmax', name='predictions')(x)
else:
if pooling == 'avg':
x = GlobalAveragePooling2D()(x)
elif pooling == 'max':
x = GlobalMaxPooling2D()(x) # 调整数据
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
if input_tensor is not None:
inputs = get_source_inputs(input_tensor)
# get_source_inputs 返回计算需要的数据列表,List of input tensors.
# 如果是tensor的数据格式,需要两步走:
# 先判断是否是keras指定的数据类型,is_keras_tensor
# 然后get_source_inputs(input_tensor)
else:
inputs = img_input # 创建模型
# Create model.
model = Model(inputs, x, name='vgg16') # 加载权重
# load weights
if weights == 'imagenet':
if include_top:
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels.h5',
WEIGHTS_PATH,
cache_subdir='models')
else:
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',
WEIGHTS_PATH_NO_TOP,
cache_subdir='models')
model.load_weights(weights_path) if K.backend() == 'theano':
layer_utils.convert_all_kernels_in_model(model) if K.image_data_format() == 'channels_first':
if include_top:
maxpool = model.get_layer(name='block5_pool')
shape = maxpool.output_shape[1:]
dense = model.get_layer(name='fc1')
layer_utils.convert_dense_weights_data_format(dense, shape, 'channels_first') if K.backend() == 'tensorflow':
warnings.warn('You are using the TensorFlow backend, yet you '
'are using the Theano '
'image data format convention '
'(`image_data_format="channels_first"`). '
'For best performance, set '
'`image_data_format="channels_last"` in '
'your Keras config '
'at ~/.keras/keras.json.')
return model if __name__ == '__main__':
model = VGG16(include_top=True, weights='imagenet') img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
print('Input image shape:', x.shape) preds = model.predict(x)
print('Predicted:', decode_predictions(preds))
# decode_predictions 输出5个最高概率:(类名, 语义概念, 预测概率)

其中: 
.

1、如何已经把模型下载到本地

==============

模型已经下载,不再每次从网站进行加载,可以修改以下内容。

WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5' weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels.h5',
WEIGHTS_PATH,
cache_subdir='models')
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',
WEIGHTS_PATH_NO_TOP,
cache_subdir='models')

.

2、几个layer中的新用法

==============

from keras.applications.imagenet_utils import decode_predictions
decode_predictions 输出5个最高概率:(类名, 语义概念, 预测概率) decode_predictions(y_pred) from keras.applications.imagenet_utils import preprocess_input
预处理 图像编码服从规定,譬如,RGB,GBR这一类的,preprocess_input(x) from keras.applications.imagenet_utils import _obtain_input_shape
确定适当的输入形状,相当于opencv中的read.img,将图像变为数组

(1)decode_predictions用在最后输出结果上,比较好用【print(‘Predicted:’, decode_predictions(preds))】; 
(2)preprocess_input,改变编码,【preprocess_input(x)】; 
(3)_obtain_input_shape 
相当于caffe中的transform,在预测的时候,需要对预测的图片进行一定的预处理。

 input_shape = _obtain_input_shape(input_shape,
default_size=224,
min_size=48,
# 模型所能接受的最小长宽
data_format=K.image_data_format(),
# 数据的使用格式
include_top=include_top)

.

3、当include_top=True时

====================

fc_model = VGG16(include_top=True)
notop_model = VGG16(include_top=False)

之前提到过用VGG16做fine-tuning的时候,得到的notop_model就是没有全连接层的模型。然后再去添加自己的层。 
当时健全的网络结构的时候,fc_model需要添加以下的内容以补全网络结构:

x = Flatten(name='flatten')(x)
x = Dense(4096, activation='relu', name='fc1')(x)
x = Dense(4096, activation='relu', name='fc2')(x)
x = Dense(classes, activation='softmax', name='predictions')(x)

pool层之后接一个flatten层,修改数据格式,然后接两个dense层,最后有softmax的Dense层。 
.

4、如果输入的数据格式是channels_first?

===========================

如果input的格式是’channels_first’,fc_model还需要修改一下格式,因为VGG16源码是以’channels_last’定义的,所以需要转换一下输出格式。

 maxpool = model.get_layer(name='block5_pool')
# model.get_layer()依据层名或下标获得层对象
shape = maxpool.output_shape[1:]
# 获取block5_pool层输出的数据格式
dense = model.get_layer(name='fc1')
layer_utils.convert_dense_weights_data_format(dense, shape, 'channels_first')

其中layer_utils.convert_dense_weights_data_format的作用很特殊,官方文档中没有说明,本质用来修改数据格式,因为层中有Flatter层把数据格式换了,所以需要再修改一下。 
原文:

When porting the weights of a convnet from one data format to the other,if the convnet includes a Flatten layer (applied to the last convolutional feature map) followed by a Dense layer, the weights of that Dense layer should be updated to reflect the new dimension ordering.

.


三、keras-Sequential-VGG16源码解读:序列式

本节节选自Keras中文文档《CNN眼中的世界:利用Keras解释CNN的滤波器》

已训练好VGG16和VGG19模型的权重: 
国外:https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3 
国内:http://files.heuritech.com/weights/vgg16_weights.h5

前面是VGG16架构的函数式模型的结构,那么在官方文档这个案例中,也有VGG16架构的序列式,都拿来比对一下比较好。 
.

1、VGG16的Sequential-网络结构


首先,我们在Keras中定义VGG网络的结构:

from keras.models import Sequential
from keras.layers import Convolution2D, ZeroPadding2D, MaxPooling2D img_width, img_height = 128, 128 # build the VGG16 network
model = Sequential()
model.add(ZeroPadding2D((1, 1), batch_input_shape=(1, 3, img_width, img_height)))
first_layer = model.layers[-1]
# this is a placeholder tensor that will contain our generated images
input_img = first_layer.input # build the rest of the network
model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2))) model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2))) model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2))) model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2))) model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2))) # get the symbolic outputs of each "key" layer (we gave them unique names).
layer_dict = dict([(layer.name, layer) for layer in model.layers])

从使用Convolution2D来看,是比较早的版本写的。 
.

2、Sequential模型如何部分layer载入权重


下面,我们将预训练好的权重载入模型,一般而言我们可以通过model.load_weights()载入,但这种办法是载入全部的权重,并不适用。 
之前所看到的No_top模型就是用来应付此时的。 
这里我们只载入一部分参数,用的是set_weights()函数,所以我们需要手工载入:

import h5py

weights_path = '.../vgg16_weights.h5'

f = h5py.File(weights_path)
for k in range(f.attrs['nb_layers']):
if k >= len(model.layers):
break
g = f['layer_{}'.format(k)]
weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
model.layers[k].set_weights(weights)
f.close()
print('Model loaded.')

笔者在实践过程中,并没有实践出来,因为我载入的.h5,不知道为什么没有属性f.attrs[‘nb_layers’]也没有属性g.attrs[‘nb_params’]) 
在寻找答案的过程中,看到有前人也跟我一样的问题,可见([keras]猫狗大战的总结):

    • Q1.f.attrs[‘nb_layers’]是什么意思?我看h5py中没有’nb_layers’的属性啊?attrs是指向f中的属性,点击右键可以看见这个属性(在HDF5-viewer)
    • Q2.g= f[‘layer_{}’.format(k)]的含义,.format的作用 
      format是格式化的意思,输出g就是format(k)填充到{}上
    • Q3.weights = [g[‘param_{}’.format(p)] for p 
      inrange(g.attrs[‘nb_params’])]的含义 得到的是layer下param_0、param_1等 
      这里用到的是set_weights(weights),weights设置的大小应与该层网络大小一致,否则会报错。

keras系列︱Application中五款已训练模型、VGG16框架(Sequential式、Model式)解读(二)的更多相关文章

  1. Keras(二)Application中五款已训练模型、VGG16框架解读

    Application的五款已训练模型 + H5py简述 Keras的应用模块Application提供了带有预训练权重的Keras模型,这些模型可以用来进行预测.特征提取和finetune. 后续还 ...

  2. 我的Keras使用总结(4)——Application中五款预训练模型学习及其应用

    本节主要学习Keras的应用模块 Application提供的带有预训练权重的模型,这些模型可以用来进行预测,特征提取和 finetune,上一篇文章我们使用了VGG16进行特征提取和微调,下面尝试一 ...

  3. 来,带你鸟瞰 Java 中4款常用的并发框架!

    1. 为什么要写这篇文章 几年前 NoSQL 开始流行的时候,像其他团队一样,我们的团队也热衷于令人兴奋的新东西,并且计划替换一个应用程序的数据库. 但是,当深入实现细节时,我们想起了一位智者曾经说过 ...

  4. Linux系统中五款好用的日志分析工具

    监控网络活动是一项繁琐的工作,但有充分的理由这样做.例如,它允许你查找和调查工作站和连接到网络的设备及服务器上的可疑登录,同时确定管理员滥用了什么.你还可以跟踪软件安装和数据传输,以实时识别潜在问题, ...

  5. keras系列︱迁移学习:利用InceptionV3进行fine-tuning及预测、完美案例(五)

    引自:http://blog.csdn.net/sinat_26917383/article/details/72982230 之前在博客<keras系列︱图像多分类训练与利用bottlenec ...

  6. keras系列︱Sequential与Model模型、keras基本结构功能(一)

    引自:http://blog.csdn.net/sinat_26917383/article/details/72857454 中文文档:http://keras-cn.readthedocs.io/ ...

  7. keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四)

    引自:http://blog.csdn.net/sinat_26917383/article/details/72885715 人脸识别热门,表情识别更加.但是表情识别很难,因为人脸的微表情很多,本节 ...

  8. keras系列︱图像多分类训练与利用bottleneck features进行微调(三)

    引自:http://blog.csdn.net/sinat_26917383/article/details/72861152 中文文档:http://keras-cn.readthedocs.io/ ...

  9. Spring Boot干货系列:(五)开发Web应用JSP篇

    Spring Boot干货系列:(五)开发Web应用JSP篇 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 上一篇介绍了Spring Boot中使用Thymeleaf模板引擎,今天 ...

随机推荐

  1. .net自定义控件Control、WebControl、CompositeControl

    一.呈现方法 1.Control主要有以下4个方法用于呈现 //该方法为入口方法 public virtual void RenderControl (HtmlTextWriter writer) { ...

  2. Android资源文件 - 使用资源存储字符串 颜色 尺寸 整型 布尔值 数组

    一. Android资源文件简介 1. Android应用资源的作用 (1) Android项目中文件分类 在Android工程中, 文件主要分为下面几类 : 界面布局文件, Java src源文件, ...

  3. Cadence 5141 下TSMC 05U工艺库安装

    以下资料摘自:<T13RF PDK簡介>-張文旭 观念与TSMC工艺库的安装 管理者安裝TSMC 0.13 MS/RF的環境下之PDK的安裝方式相當容易,首先以root的方式進入Unix/ ...

  4. uiautomatorviewer 查看元素新思路

    用adb 命令把图片和uix获取出来,再导入uiautomatorviewer adb shell uiautomator dump /data/local/tmp/uidump.uixadb pul ...

  5. Chrome封掉不在chrome商店中的插件解决办法

    添加chrome的管理模板,chrome.adm文件:下载地址:链接:http://pan.baidu.com/s/1c08st7i 密码: e811 然后进行如下的设置,重启chrome就可以解除封 ...

  6. 在linux中配置环境变量

    JDK下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 根据Linux ...

  7. 配置ssh的config文件-为每个ssh连接创建别名

    其实选来选去,还是iterm2就够用了,唯一比较麻烦的就是每次都有输入地址和用户名,其实,可以通过配置文件简写的. 可以在 ~/.ssh/config文件写上配置alias信息,以后ssh的时候根据a ...

  8. ios页面间跳转方式总结

    转自:http://www.cnblogs.com/anywherego/p/3542202.html 下面以OldViewController(oldC)的按钮btn点击后跳转到NewViewCon ...

  9. C#中自定义属性的例子

    自定义属性的作用 有时候我们需要给一个类或者类中的成员加上一些属性或者附加信息,让类或者变量的功能更明确可控制的细粒度更高,打个简单的比方:数据库里面的一张表,表中的每一个字段都有很多属性,如是否主键 ...

  10. Linux下找不到so文件的解决办法

    http://www.cnblogs.com/xudong-bupt/p/3698294.html 如果使用自己手动生成的动态链接库.so文件,但是这个.so文件,没有加入库文件搜索路劲中,程序运行时 ...