更新时间:2023-12-15 gmt 08:00
tensorflow-凯发k8国际娱乐官网入口
tensorflow存在两种接口类型,keras接口和tf接口,其训练和保存模型的代码存在差异,但是推理代码编写方式一致。
训练模型(keras接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
from keras.models import sequential
model = sequential()
from keras.layers import dense
import tensorflow as tf
# 导入训练数据集
mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
print(x_train.shape)
from keras.layers import dense
from keras.models import sequential
import keras
from keras.layers import dense, activation, flatten, dropout
# 定义模型网络
model = sequential()
model.add(flatten(input_shape=(28,28)))
model.add(dense(units=5120,activation='relu'))
model.add(dropout(0.2))
model.add(dense(units=10, activation='softmax'))
# 定义优化器,损失函数等
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.summary()
# 训练
model.fit(x_train, y_train, epochs=2)
# 评估
model.evaluate(x_test, y_test)
|
保存模型(keras接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
from keras import backend as k
# k.get_session().run(tf.global_variables_initializer())
# 定义预测接口的inputs和outputs
# inputs和outputs字典的key值会作为模型输入输出tensor的索引键
# 模型输入输出定义需要和推理自定义脚本相匹配
predict_signature = tf.saved_model.signature_def_utils.predict_signature_def(
inputs={"images" : model.input},
outputs={"scores" : model.output}
)
# 定义保存路径
builder = tf.saved_model.builder.savedmodelbuilder('./mnist_keras/')
builder.add_meta_graph_and_variables(
sess = k.get_session(),
# 推理部署需要定义tf.saved_model.tag_constants.serving标签
tags=[tf.saved_model.tag_constants.serving],
"""
signature_def_map:items只能有一个,或者需要定义相应的key为
tf.saved_model.signature_constants.default_serving_signature_def_key
"""
signature_def_map={
tf.saved_model.signature_constants.default_serving_signature_def_key:
predict_signature
}
)
builder.save()
|
训练模型(tf接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
from __future__ import print_function
import gzip
import os
import urllib
import numpy
import tensorflow as tf
from six.moves import urllib
# 训练数据来源于yann lecun官方网站http://yann.lecun.com/exdb/mnist/
source_url = 'http://yann.lecun.com/exdb/mnist/'
train_images = 'train-images-idx3-ubyte.gz'
train_labels = 'train-labels-idx1-ubyte.gz'
test_images = 't10k-images-idx3-ubyte.gz'
test_labels = 't10k-labels-idx1-ubyte.gz'
validation_size = 5000
def maybe_download(filename, work_directory):
"""download the data from yann's website, unless it's already here."""
if not os.path.exists(work_directory):
os.mkdir(work_directory)
filepath = os.path.join(work_directory, filename)
if not os.path.exists(filepath):
filepath, _ = urllib.request.urlretrieve(source_url filename, filepath)
statinfo = os.stat(filepath)
print('successfully downloaded %s%d bytes.' % (filename, statinfo.st_size))
return filepath
def _read32(bytestream):
dt = numpy.dtype(numpy.uint32).newbyteorder('>')
return numpy.frombuffer(bytestream.read(4), dtype=dt)[0]
def extract_images(filename):
"""extract the images into a 4d uint8 numpy array [index, y, x, depth]."""
print('extracting %s' % filename)
with gzip.open(filename) as bytestream:
magic = _read32(bytestream)
if magic != 2051:
raise valueerror(
'invalid magic number %d in mnist image file: %s' %
(magic, filename))
num_images = _read32(bytestream)
rows = _read32(bytestream)
cols = _read32(bytestream)
buf = bytestream.read(rows * cols * num_images)
data = numpy.frombuffer(buf, dtype=numpy.uint8)
data = data.reshape(num_images, rows, cols, 1)
return data
def dense_to_one_hot(labels_dense, num_classes=10):
"""convert class labels from scalars to one-hot vectors."""
num_labels = labels_dense.shape[0]
index_offset = numpy.arange(num_labels) * num_classes
labels_one_hot = numpy.zeros((num_labels, num_classes))
labels_one_hot.flat[index_offset labels_dense.ravel()] = 1
return labels_one_hot
def extract_labels(filename, one_hot=false):
"""extract the labels into a 1d uint8 numpy array [index]."""
print('extracting %s' % filename)
with gzip.open(filename) as bytestream:
magic = _read32(bytestream)
if magic != 2049:
raise valueerror(
'invalid magic number %d in mnist label file: %s' %
(magic, filename))
num_items = _read32(bytestream)
buf = bytestream.read(num_items)
labels = numpy.frombuffer(buf, dtype=numpy.uint8)
if one_hot:
return dense_to_one_hot(labels)
return labels
class dataset(object):
"""class encompassing test, validation and training mnist data set."""
def __init__(self, images, labels, fake_data=false, one_hot=false):
"""construct a dataset. one_hot arg is used only if fake_data is true."""
if fake_data:
self._num_examples = 10000
self.one_hot = one_hot
else:
assert images.shape[0] == labels.shape[0], (
'images.shape: %s labels.shape: %s' % (images.shape,
labels.shape))
self._num_examples = images.shape[0]
# convert shape from [num examples, rows, columns, depth]
# to [num examples, rows*columns] (assuming depth == 1)
assert images.shape[3] == 1
images = images.reshape(images.shape[0],
images.shape[1] * images.shape[2])
# convert from [0, 255] -> [0.0, 1.0].
images = images.astype(numpy.float32)
images = numpy.multiply(images, 1.0 / 255.0)
self._images = images
self._labels = labels
self._epochs_completed = 0
self._index_in_epoch = 0
@property
def images(self):
return self._images
@property
def labels(self):
return self._labels
@property
def num_examples(self):
return self._num_examples
@property
def epochs_completed(self):
return self._epochs_completed
def next_batch(self, batch_size, fake_data=false):
"""return the next `batch_size` examples from this data set."""
if fake_data:
fake_image = [1] * 784
if self.one_hot:
fake_label = [1] [0] * 9
else:
fake_label = 0
return [fake_image for _ in range(batch_size)], [
fake_label for _ in range(batch_size)
]
start = self._index_in_epoch
self._index_in_epoch = batch_size
if self._index_in_epoch > self._num_examples:
# finished epoch
self._epochs_completed = 1
# shuffle the data
perm = numpy.arange(self._num_examples)
numpy.random.shuffle(perm)
self._images = self._images[perm]
self._labels = self._labels[perm]
# start next epoch
start = 0
self._index_in_epoch = batch_size
assert batch_size <= self._num_examples
end = self._index_in_epoch
return self._images[start:end], self._labels[start:end]
def read_data_sets(train_dir, fake_data=false, one_hot=false):
"""return training, validation and testing data sets."""
class datasets(object):
pass
data_sets = datasets()
if fake_data:
data_sets.train = dataset([], [], fake_data=true, one_hot=one_hot)
data_sets.validation = dataset([], [], fake_data=true, one_hot=one_hot)
data_sets.test = dataset([], [], fake_data=true, one_hot=one_hot)
return data_sets
local_file = maybe_download(train_images, train_dir)
train_images = extract_images(local_file)
local_file = maybe_download(train_labels, train_dir)
train_labels = extract_labels(local_file, one_hot=one_hot)
local_file = maybe_download(test_images, train_dir)
test_images = extract_images(local_file)
local_file = maybe_download(test_labels, train_dir)
test_labels = extract_labels(local_file, one_hot=one_hot)
validation_images = train_images[:validation_size]
validation_labels = train_labels[:validation_size]
train_images = train_images[validation_size:]
train_labels = train_labels[validation_size:]
data_sets.train = dataset(train_images, train_labels)
data_sets.validation = dataset(validation_images, validation_labels)
data_sets.test = dataset(test_images, test_labels)
return data_sets
training_iteration = 1000
modelarts_example_path = './modelarts-mnist-train-save-deploy-example'
export_path = modelarts_example_path '/model/'
data_path = './'
print('training model...')
mnist = read_data_sets(data_path, one_hot=true)
sess = tf.interactivesession()
serialized_tf_example = tf.placeholder(tf.string, name='tf_example')
feature_configs = {'x': tf.fixedlenfeature(shape=[784], dtype=tf.float32), }
tf_example = tf.parse_example(serialized_tf_example, feature_configs)
x = tf.identity(tf_example['x'], name='x') # use tf.identity() to assign name
y_ = tf.placeholder('float', shape=[none, 10])
w = tf.variable(tf.zeros([784, 10]))
b = tf.variable(tf.zeros([10]))
sess.run(tf.global_variables_initializer())
y = tf.nn.softmax(tf.matmul(x, w) b, name='y')
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
train_step = tf.train.gradientdescentoptimizer(0.01).minimize(cross_entropy)
values, indices = tf.nn.top_k(y, 10)
table = tf.contrib.lookup.index_to_string_table_from_tensor(
tf.constant([str(i) for i in range(10)]))
prediction_classes = table.lookup(tf.to_int64(indices))
for _ in range(training_iteration):
batch = mnist.train.next_batch(50)
train_step.run(feed_dict={x: batch[0], y_: batch[1]})
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'))
print('training accuracy %g' % sess.run(
accuracy, feed_dict={
x: mnist.test.images,
y_: mnist.test.labels
}))
print('done training!')
|
保存模型(tf接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# 导出模型
# 模型需要采用saved_model接口保存
print('exporting trained model to', export_path)
builder = tf.saved_model.builder.savedmodelbuilder(export_path)
tensor_info_x = tf.saved_model.utils.build_tensor_info(x)
tensor_info_y = tf.saved_model.utils.build_tensor_info(y)
# 定义预测接口的inputs和outputs
# inputs和outputs字典的key值会作为模型输入输出tensor的索引键
# 模型输入输出定义需要和推理自定义脚本相匹配
prediction_signature = (
tf.saved_model.signature_def_utils.build_signature_def(
inputs={'images': tensor_info_x},
outputs={'scores': tensor_info_y},
method_name=tf.saved_model.signature_constants.predict_method_name))
legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op')
builder.add_meta_graph_and_variables(
# tag设为serve/tf.saved_model.tag_constants.serving
sess, [tf.saved_model.tag_constants.serving],
signature_def_map={
'predict_images':
prediction_signature,
},
legacy_init_op=legacy_init_op)
builder.save()
print('done exporting!')
|
推理代码(keras接口和tf接口)
在模型代码推理文件customize_service.py中,需要添加一个子类,该子类继承对应模型类型的父类,各模型类型的父类名称和导入语句如请参考。本案例中调用父类“_inference(self, data)”推理请求方法,因此下文代码中不需要重写方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
from pil import image
import numpy as np
from model_service.tfserving_model_service import tfservingbaseservice
class mnistservice(tfservingbaseservice):
# 预处理中处理用户https接口输入匹配模型输入
# 对应上述训练部分的模型输入为{"images":
|
父主题:
意见反馈
文档内容是否对您有帮助?
提交成功!非常感谢您的反馈,我们会继续努力做到更好!
您可在查看反馈及问题处理状态。
系统繁忙,请稍后重试
如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨