1.tf.train.batch(image, batch_size=batch_size, num_threads=1) # 获取一个batch的数据

参数说明:image表示输入图片,batch_size表示一个batch的大小,num_threads表示使用几个线程进行执行

  1. import tensorflow as tf
  2. import numpy as np
  3. def generate_data():
  4.  
  5. num = 25
  6. label = np.asarray(range(0, num))
  7. image = np.random.random([num, 1, 1, 1])
  8.  
  9. return label, image
  10.  
  11. def get_batch_data():
  12.  
  13. labels, images = generate_data()
  14. images = tf.cast(images, 'float32')
  15. labels = tf.cast(labels, 'int32')
  16. input_queue = tf.train.slice_input_producer([images, labels], shuffle=False)
  17. image_batch, label_batch = tf.train.batch(input_queue, batch_size=10, num_threads=1, capacity=64)
  18.  
  19. return image_batch, label_batch
  20.  
  21. image_batch, label_batch = get_batch_data()
  22. with tf.Session() as sess:
  23. coord = tf.train.Coordinator()
  24. threads = tf.train.start_queue_runners(sess=sess, coord=coord)
  25. i = 0
  26. for i in range(10):
  27. image_batch_v, label_batch_v = sess.run([image_batch, label_batch])
  28. print(image_batch_v, label_batch_v)
  29.  
  30. coord.request_stop()
  31. coord.join(threads)
  32. sess.close()

实例说明

2.tf.image.resize_image_with_crop_or_pad(image, IMAGE_SIZE, IMAGE_SIZE) # 表示对图片进行压缩,即变化维度, 相当于tf.resize(操作)

参数说明:image表示输入图片,IMAGE_SIZE表示变化后的维度

3.tf.train.per_image_standardization(image) 对图片进行标准化操作

参数说明:image表示输入的图片

4.tf.train.string_input_producer(filenames) # 将字符串放入到队列中

参数说明:filename表示输入的字符串集合

5. tf.TFRecordReader() # 构建tfr读取器,使用.read() 对文件进行读取

6. tf.parse_single_example(serialized_exmaple, features={})  解析example数据字符串

7.tf.train.start_queue_runner(coord=coord, sess=sess) 用来启动线程,进行多线程操作

参数说明:coord表示线程协调器,sess执行函数支持多线程

8.tf.train.Coordinator() 用于建立线程协调器, coord.join(threads) 将多线程放入到线程协调器中

数据说明:使用的数据是Tfrecord数据集,一共3670个数据,每次迭代选取16张图片,输出的结果类别数是5

文中的代码主要是分为两个部分:

第一部分构造flower_input, 读取batch_image, batch_label

第二部分:构造image_tensor_input和label_tensor_input, 输入到构造的flower_inference模型中进行训练,输出结果为softmax概率值,构造loss和train_op,sess.run进行模型的训练操作

第一部分:

第一步:构造flower_input函数,输入为if_random, if_train

第二步:根据是否训练,使用[os.path.join(path_data + ''%i) for i in range(0, 2)] 来获得文件的路径filenames

第三步:使用tf.train.string_input_producer(filenames) , # 输出字符变成一个输入队列中

第四步:将filename_queue输入到read_and_decode(filename_queue) 输出image_object实例化对象,包含image, label, filename等属性

第一步:使用tf.TFRecordReader() 构造reader的读写器

第二步:使用_, serialized_example = reader.read(filenames)  获得存储好的example

第三步:使用tf.parse_single_example(features={})  获得属性值

第四步:实例化_image_object(), 用于储存image,label, filename,width和height

第五步:使用image_raw = tf.image.decode_jpeg(feature[image/encoded]) # 对图片进行解码操作

第六步:使用tf.image.resize_image_with_crop_or_pad(image_raw) 对图像进行维度的压缩变换

第七步:将其他属性label,filename, height,width,使用image_object.label = features['image/labels'] 进行添加, 返回image_object

第五步:使用image_object.image 获得image, 使用tf.train.per_image_standardization对image进行标准化操作

第六步:使用image_object.label获得label属性

第七步:使用image_object.filename获得filename属性

第八步:判断是否是随机的batch,如果是随机的使用tf.train.shuffle_batch,如果不是随机的batch,使用tf.train.batch([image, label, filename]) 获得随机的batch,返回image_batch, label_batch, filename_batch

第二部分:第一部分,获得了一个batch的数据, 第二部分,建立网络模型

第一步:使用tf.placeholder()构建image_tensor_input, 同时对image_batch_out 进行维度的变化,确认其维度为[BATCH_SIZE, 224, 224, 3]

第二步:使用tf.placeholder()构建label_tensor_input,同时构造label_offset = -tf.ones([batch_size]) ,然后使用tf.add(label_batch_out, label_offset) 将标签值从1变为0。

第三步:构造flower_inference(image_tensor_input)获得logits_batch_out, 对logists_batch 进行维度变化,确认其维度为[BATCH_SIZE, 5]

flower_inference是用于构造卷积的模型,网络的结构是卷积层5层,全连接层4层,输出层为[BATCH_SIZE, 5], 结果使用tf.nn.softmax()

第四步: 使用tf.nn.softmax_entropy_logits(logits=logits_out, labels=tf.one_hots(label_tensor_input, depth=5))  构造loss损失函数

第五步:使用tf.train.GradientDescentOptimizer().minimize(loss) 构造train_op,降低损失值

第六步:使用with tf.Session() as sess 构造sess执行函数

第七步:使用sess.run, 进行变量的初始化操作

第八步:使用tf.train.Coordinator() 构造coord通道,使用tf.train.start_queue_runners(coord=coord, sess=sess) 构造threads多线程

第九步:进行循环,使用sess.run([image_batch, label_batch]) 获得实际的image_batch 和 label_batch

第十步:使用sess.run([train_op, logits_out, loss]) 进行训练操作

第十一步:coord.request_stop() 将coord进行关闭

第十二步:coord.join(threads) 将多线程添加到通道数,sess.close() 关闭sess

  1. import tensorflow as tf
  2. import numpy as np
  3. import os
  4.  
  5. data_path = './data/'
  6. TRAINING_SET_SIZE = 3670
  7. BATCH_SIZE = 16
  8. IMAGE_SIZE = 224
  9.  
  10. def create_Weight(shape):
  11.  
  12. return tf.Variable(tf.truncated_normal(shape=shape, stddev=0.05))
  13.  
  14. def creat_biases(shape):
  15.  
  16. return tf.Variable(tf.constant(0.1, shape=shape))
  17.  
  18. def conv2d(x, w):
  19.  
  20. return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')
  21.  
  22. def maxpool(x):
  23.  
  24. return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
  25.  
  26. def flower_inference(image_tensor_input):
  27.  
  28. # 确认输入的图片的维度为[batchsize, 224, 224, 5]
  29. x_image = tf.reshape(image_tensor_input, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3])
  30. # 创建第一层卷积的w
  31. w_conv1 = create_Weight([5, 5, 3, 32])
  32. # 第一层卷积的b
  33. b_conv1 = creat_biases([32])
  34. # 进行卷积和激活操作
  35. h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
  36. # 进行池化操作
  37. h_pool1 = maxpool(h_conv1)
  38. # 第二层卷积的w
  39. w_conv2 = create_Weight([5, 5, 32, 64])
  40. # 第二层卷积的b
  41. b_conv2 = creat_biases([64])
  42. # 卷积和激活操作
  43. h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2)
  44. # 池化操作
  45. h_pool2 = maxpool(h_conv2)
  46. # 第三层卷积的w
  47. w_conv3 = create_Weight([5, 5, 64, 128])
  48. # 第三层卷积的b
  49. b_conv3 = creat_biases([128])
  50. # 卷积和激活操作
  51. h_conv3 = tf.nn.relu(conv2d(h_pool2, w_conv3) + b_conv3)
  52. # 池化操作
  53. h_pool3 = maxpool(h_conv3)
  54. # 第四层卷积的w
  55. w_conv4 = create_Weight([5, 5, 128, 256])
  56. # 第四层卷积的b
  57. b_conv4 = creat_biases([256])
  58. # 进行卷积和激活操作
  59. h_conv4 = tf.nn.relu(conv2d(h_pool3, w_conv4) + b_conv4)
  60. # 进行池化操作
  61. h_pool4 = maxpool(h_conv4)
  62. # 第五层卷积的w
  63. w_conv5 = create_Weight([5, 5, 256, 256])
  64. # 第五层卷积的b
  65. b_conv5 = creat_biases([256])
  66. # 进行卷积和激活操作
  67. h_conv5 = tf.nn.relu(conv2d(h_pool4, w_conv5) + b_conv5)
  68. # 池化操作
  69. h_pool5 = maxpool(h_conv5)
  70. # 将卷积后的结果进行维度的变换,以便后续进行全连接操作
  71. fcIn = tf.reshape(h_pool5, [-1, 7*7*256])
  72. # 第一层全连接的w
  73. w_fc1 = create_Weight([7*7*256, 2048])
  74. # 第一层全连接的b
  75. b_fc1 = creat_biases([2048])
  76. # 点乘和激活操作
  77. h_fc1 = tf.nn.relu(tf.matmul(fcIn, w_fc1) + b_fc1)
  78. # dropout操作
  79. h_fc1_dropout = tf.nn.dropout(h_fc1, 1.0)
  80. # 第二层全连接的w
  81. w_fc2 = create_Weight([2048, 256])
  82. # 第二层全连接的b
  83. b_fc2 = creat_biases([256])
  84. # 点乘和激活操作
  85. h_fc2 = tf.nn.relu(tf.matmul(h_fc1_dropout, w_fc2) + b_fc2)
  86. # 第三层全连接层
  87. w_fc3 = create_Weight([256, 64])
  88. b_fc3 = creat_biases([64])
  89. h_fc3 = tf.nn.relu(tf.matmul(h_fc2, w_fc3) +b_fc3)
  90. # 第四层全连接输出层
  91. w_fc4 = create_Weight([64, 5])
  92. b_fc4 = creat_biases([5])
  93. # 对输出的结果使用softmax获得概率值
  94. y_prob = tf.nn.softmax(tf.matmul(h_fc3, w_fc4) + b_fc4)
  95.  
  96. return y_prob
  97.  
  98. class _image_object:
  99. # 构造实例化属性
  100. def __init__(self):
  101. # 存放图片,高度,宽度,名字和标签属性
  102. self.image = tf.Variable([], dtype=tf.string)
  103. self.height = tf.Variable([], dtype=tf.int64)
  104. self.width = tf.Variable([], dtype=tf.int64)
  105. self.filename = tf.Variable([], dtype=tf.string)
  106. self.label = tf.Variable([], dtype=tf.int32)
  107.  
  108. def read_and_decode(filename_queue):
  109. # 构造TFR的读写器
  110. reader = tf.TFRecordReader()
  111. # 使用reader.read(filename_queue)读出存入的exmaple数据
  112. _, serialized_exmaple = reader.read(filename_queue)
  113. # 使用tf.parse_single_example, 获得数据中属性对应的数据
  114. features = tf.parse_single_example(serialized_exmaple, features={
  115. 'image/encoded':tf.FixedLenFeature([], tf.string),
  116. 'image/height': tf.FixedLenFeature([], tf.int64),
  117. 'image/width': tf.FixedLenFeature([], tf.int64),
  118. 'image/filename': tf.FixedLenFeature([], tf.string),
  119. 'image/class/label': tf.FixedLenFeature([], tf.int64)
  120. })
  121. # 获得编码的图片数据
  122. image_decode = features['image/encoded']
  123. # 使用tf.image.decode_jpeg 对图片进行解码操作
  124. image_raw = tf.image.decode_jpeg(image_decode, channels=3)
  125. # 实例化函数,用于进行数据集合的存储
  126. image_object = _image_object()
  127. # 使用tf.image.resize_image_with_crop_or_pad进行维度的变换和压缩,并存储到image.object
  128. image_object.image = tf.image.resize_image_with_crop_or_pad(image_raw,IMAGE_SIZE, IMAGE_SIZE)
  129. # 将label属性存储到image_object.label中
  130. image_object.label = features['image/class/label']
  131. # 将filename属性存储到image_object.filename中
  132. image_object.filename = features['image/filename']
  133. # 将height属性存储到image_object.height中
  134. image_object.height = features['image/height']
  135. # 将width属性存储到image_object.width中
  136. image_object.width = features['image/width']
  137. # 返回数据集合image_object
  138. return image_object
  139.  
  140. # 第一步:创建flower_input,用于进行数据的创建,输入为是否训练和是否获得随机的batch值
  141. def flower_input(if_train=True, if_random=True):
  142. # 第二步:如果是进行训练,获得训练集的文件地址
  143. if if_train:
  144. filenames = [os.path.join(data_path, 'train-0000%d-of-00002.tfrecord'%i) for i in range(0, 2)]
  145. else:
  146. filenames = [os.path.join(data_path, 'eval-0000%d-of-00002.tfrecord'%i) for i in range(0, 2)]
  147. # 判断文件是否存在,如果不存在返回错误提醒
  148. for f in filenames:
  149. if not tf.gfile.Exists(f):
  150. raise ValueError('the file is not exits', f)
  151. # 第三步:使用tf.train.string_input_producer()将数据输入到队列中
  152. filename_queue = tf.train.string_input_producer(filenames)
  153. # 第四步:构造函数获得数据集合
  154. image_object = read_and_decode(filename_queue)
  155. # 使用tf.image.per_image_standardization对图片进行标准化
  156. image = tf.image.per_image_standardization(image_object.image)
  157. # 获得图片的标签
  158. label = image_object.label
  159. # 获得图片的文件名
  160. filename = image_object.filename
  161. # 如果是随机获得标签,使用tf.train.shuffle_batch
  162. if if_random:
  163. min_fraction_of_example_in_queue = 0.4
  164. min_queue_examples = int(min_fraction_of_example_in_queue * TRAINING_SET_SIZE)
  165. num_preprocess_threads = 1
  166. image_batch, label_batch, filename_batch = tf.train.shuffle_batch(
  167. [image, label, filename],
  168. batch_size = BATCH_SIZE,
  169. num_threads = num_preprocess_threads,
  170. capacity = min_queue_examples + 3 * BATCH_SIZE,
  171. min_after_dequeue = min_queue_examples
  172. )
  173. # 返回batch的image,label,filename
  174. return image_batch, label_batch, filename_batch
  175. else:
  176. # 如果不是随机获得数据,使用tf.train.batch
  177. image_batch, label_batch, filename_batch = tf.train.batch(
  178. [image, label, filename],
  179. batch_size = BATCH_SIZE,
  180. num_threads = 1
  181. )
  182. #返回batch的image,label,filename
  183. return image_batch, label_batch, filename_batch
  184.  
  185. def flower_trian():
  186. # 第一部分:使用tf.train.batch获得一个batch的数据
  187. image_batch_out, label_batch_out, filename_batch = flower_input(if_train=True, if_random=False)
  188. # 第二部分:构造模型,进行模型的训练,使用sess.run()获得上述的实际数据
  189. # 第一步:使用tf.placeholder初始化输入图像,并对image_batch_out确认维度
  190. image_tensor_input = tf.placeholder(tf.float32, [BATCH_SIZE, 224, 224, 3])
  191. image_batch = tf.reshape(image_batch_out, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3])
  192. # 第二步:使用tf.placeholder初始化标签值,并构造-1的[batch_size]大小,与标签进行加和,使得标签值变成从0开始
  193. label_tensor_input = tf.placeholder(tf.int64, [BATCH_SIZE])
  194. label_offset = -tf.ones([BATCH_SIZE], dtype=tf.int64, name='label_offset')
  195. label_batch = tf.add(label_batch_out, label_offset)
  196. # 第三步:构造模型,带入image_tensor_input获得5个类别的概率值,维度为[BATCHSIZE, 5]
  197. logits_batch_out = flower_inference(image_tensor_input)
  198. logits_batch = tf.reshape(logits_batch_out, [BATCH_SIZE, 5])
  199. # 第四步:使用tf.nn.sotfmax_cross(logist=logits_batch, labels=tf.one_hot() 进行对标签进行one_hot编码
  200. loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=tf.one_hot(label_tensor_input, depth=5), logits=logits_batch))
  201. # 第五步:使用tf.train.Gradient降低损失值loss
  202. train_op = tf.train.GradientDescentOptimizer(0.0001).minimize(loss)
  203.  
  204. saver = tf.train.Saver()
  205. # 第六步:使用tf.Session() 构造sess执行函数
  206. with tf.Session() as sess:
  207. # 第七步:对参数进行初始化操作
  208. sess.run(tf.global_variables_initializer())
  209. # 第八步:使用tf.train.Coordinator构造通道数
  210. coord = tf.train.Coordinator()
  211. # 第九步:使用tf.train.start_queue_runners构造sess的多线程threads
  212. threads = tf.train.start_queue_runners(coord=coord, sess=sess)
  213.  
  214. for i in range(TRAINING_SET_SIZE * 10):
  215. # 第十步:使用sess.run获得实际的batch的label,image
  216. image_batch_v, label_batch_v, filename_batch_v = sess.run([image_batch, label_batch, filename_batch])
  217. # 第十一步:进行实际的train_op, loss, logits的执行
  218. _, infer_out, loss_out = sess.run([train_op, logits_batch, loss], feed_dict={image_tensor_input:image_batch_v, label_tensor_input:label_batch_v})
  219. # 打印结果
  220. if (i % 10 == 0):
  221. print('infer_out')
  222. print(infer_out)
  223. print('loss_out')
  224. print(loss_out)
  225. # 第十一步:关闭线程
  226. coord.request_stop()
  227. # 第十二步:将线程进行添加,和关闭sess
  228. coord.join(threads)
  229. sess.close()
  230.  
  231. flower_trian()

深度学习原理与框架-Tfrecord数据集的读取与训练(代码) 1.tf.train.batch(获取batch图片) 2.tf.image.resize_image_with_crop_or_pad(图片压缩) 3.tf.train.per_image_stand..(图片标准化) 4.tf.train.string_input_producer(字符串入队列) 5.tf.TFRecord(读的更多相关文章

  1. 深度学习原理与框架-Tfrecord数据集的制作 1.tf.train.Examples(数据转换为二进制) 3.tf.image.encode_jpeg(解码图片加码成jpeg) 4.tf.train.Coordinator(构建多线程通道) 5.threading.Thread(建立单线程) 6.tf.python_io.TFR(TFR读入器)

    1. 配套使用: tf.train.Examples将数据转换为二进制,提升IO效率和方便管理 对于int类型 : tf.train.Examples(features=tf.train.Featur ...

  2. 深度学习原理与框架-图像补全(原理与代码) 1.tf.nn.moments(求平均值和标准差) 2.tf.control_dependencies(先执行内部操作) 3.tf.cond(判别执行前或后函数) 4.tf.nn.atrous_conv2d 5.tf.nn.conv2d_transpose(反卷积) 7.tf.train.get_checkpoint_state(判断sess是否存在

    1. tf.nn.moments(x, axes=[0, 1, 2])  # 对前三个维度求平均值和标准差,结果为最后一个维度,即对每个feature_map求平均值和标准差 参数说明:x为输入的fe ...

  3. 深度学习原理与框架-CNN在文本分类的应用 1.tf.nn.embedding_lookup(根据索引数据从数据中取出数据) 2.saver.restore(加载sess参数)

    1. tf.nn.embedding_lookup(W, X) W的维度为[len(vocabulary_list), 128], X的维度为[?, 8],组合后的维度为[?, 8, 128] 代码说 ...

  4. 深度学习原理与框架-递归神经网络-RNN_exmaple(代码) 1.rnn.BasicLSTMCell(构造基本网络) 2.tf.nn.dynamic_rnn(执行rnn网络) 3.tf.expand_dim(增加输入数据的维度) 4.tf.tile(在某个维度上按照倍数进行平铺迭代) 5.tf.squeeze(去除维度上为1的维度)

    1. rnn.BasicLSTMCell(num_hidden) #  构造单层的lstm网络结构 参数说明:num_hidden表示隐藏层的个数 2.tf.nn.dynamic_rnn(cell, ...

  5. 深度学习原理与框架-猫狗图像识别-卷积神经网络(代码) 1.cv2.resize(图片压缩) 2..get_shape()[1:4].num_elements(获得最后三维度之和) 3.saver.save(训练参数的保存) 4.tf.train.import_meta_graph(加载模型结构) 5.saver.restore(训练参数载入)

    1.cv2.resize(image, (image_size, image_size), 0, 0, cv2.INTER_LINEAR) 参数说明:image表示输入图片,image_size表示变 ...

  6. 深度学习原理与框架-Alexnet(迁移学习代码) 1.sys.argv[1:](控制台输入的参数获取第二个参数开始) 2.tf.split(对数据进行切分操作) 3.tf.concat(对数据进行合并操作) 4.tf.variable_scope(指定w的使用范围) 5.tf.get_variable(构造和获得参数) 6.np.load(加载.npy文件)

    1. sys.argv[1:]  # 在控制台进行参数的输入时,只使用第二个参数以后的数据 参数说明:控制台的输入:python test.py what, 使用sys.argv[1:],那么将获得w ...

  7. 深度学习原理与框架-Tensorflow卷积神经网络-cifar10图片分类(代码) 1.tf.nn.lrn(局部响应归一化操作) 2.random.sample(在列表中随机选值) 3.tf.one_hot(对标签进行one_hot编码)

    1.tf.nn.lrn(pool_h1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75) # 局部响应归一化,使用相同位置的前后的filter进行响应归一化操作 参数 ...

  8. 深度学习原理与框架-Tensorflow基本操作-变量常用操作 1.tf.random_normal(生成正态分布随机数) 2.tf.random_shuffle(进行洗牌操作) 3. tf.assign(赋值操作) 4.tf.convert_to_tensor(转换为tensor类型) 5.tf.add(相加操作) tf.divide(相乘操作) 6.tf.placeholder(输入数据占位

    1. 使用tf.random_normal([2, 3], mean=-1, stddev=4) 创建一个正态分布的随机数 参数说明:[2, 3]表示随机数的维度,mean表示平均值,stddev表示 ...

  9. 深度学习原理与框架-神经网络-cifar10分类(代码) 1.np.concatenate(进行数据串接) 2.np.hstack(将数据横着排列) 3.hasattr(判断.py文件的函数是否存在) 4.reshape(维度重构) 5.tanspose(维度位置变化) 6.pickle.load(f文件读入) 7.np.argmax(获得最大值索引) 8.np.maximum(阈值比较)

    横1. np.concatenate(list, axis=0) 将数据进行串接,这里主要是可以将列表进行x轴获得y轴的串接 参数说明:list表示需要串接的列表,axis=0,表示从上到下进行串接 ...

随机推荐

  1. ubuntu 使用cron设置定时启动任务

    介绍 cron,是一个Linux定时执行工具,可以在无需人工干预的情况下运行作业. 在Ubuntu server 下,cron是被默认安装并启动的:如果没有启动,自行设置并启动(chkconfig\s ...

  2. Django安装遇到的问题

    因为mac一般自带的有python解释器,如果重新安装了新的解释器,并且想默认使用的话,需要配置一下环境变量. 在使用python解释器的时候,可以用命令:which python 来确定当前使用的时 ...

  3. mysql数据库的基本操作命令整理

    快捷键 ctrl+l 清屏 ctrl +a 回到行首 ctrl + e 回到行末   数据库操作 进入数据库 方式1 mysql -u用户名 -p 密码 --------直接输入密码,缺点,会暴露自己 ...

  4. SQL注入之Sqli-labs系列第三十四关(基于宽字符逃逸POST注入)和三十五关

    开始挑战第三十四关和第三十五关(Bypass add addslashes) 0x1查看源码 本关是post型的注入漏洞,同样的也是将post过来的内容进行了 ' \ 的处理. if(isset($_ ...

  5. testDecoration

    def count(): fs = [] for i in range(1,4): def f(): n=i*i return n fs.append(f) return fs c1,c2,c3 = ...

  6. Java 8 中常用的函数式接口

    函数式接口 函数描述符 Predicate<T> T->boolean Consumer<T> T->void Function<T, R> T-> ...

  7. 单例模式demo

    package com.test; /** * * @author Administrator *我的发现:调用这个的时候,不能直接实例化了;需要=null;然后get; 这样安全些; *然后仔细找了 ...

  8. MYSQL之IFNULL

    IFNULL是MYSQL中的一个判断字段值是否为null的函数,如果为null,则此查询可以变更为指定的值: 如 IFNULL(a,0)  如果a为null,则查询出0. 如果A表中没有数据 sele ...

  9. spring mvc 为什么这么多xml

    spring web mvc 处理流程 Architecture web.xml (webapp必要配置) 作用:spring web mvc 使用dispatcherServlet 分发reques ...

  10. 重读 谢希仁《计算机网络》3 - 网络层和IP协议