发布时间:2025-12-10 11:34:31 浏览次数:4
构成基本部件就是layer,一个layer除了包含其shape,还有其weights,shape和weights构成了layer的基础。
通常我们构建网络代码如下:
这个就是一个最简单的三层网络:输入层,隐藏层,输出层
相信大家也了解到了shape和weights是配套的,虽然我们画图是三层,在tensorflow里对应的是2层。
输出层和损失计算是在同一层,一般把最后一层叫做costlayer,正因为如此,我们预测时只用输出层
的weights,不需要使用输出层计算损失的过程。
在这里不要纠结使用tensorflow的方法来实现tensorflow,我们只是了解tensorflow的代码结构,实际都可以自己写。
layer有一个变量和一个方法:shape和activate
from abc import ABCMeta, abstractmethodclass Layer():__metaclass__ = ABCMetadef __init__(self, shape):self.shape = shapedef activate(self, x, w, bias=None, predict=False):if bias is None:return self._activate(tf.matmul(x, w), predict)return self._activate(tf.matmul(x, w) + bias, predict)@abstractmethoddef _activate(self, x, predict):pass# Activation Layersclass Tanh(Layer):def _activate(self, x, predict):return tf.tanh(x)class Sigmoid(Layer):def _activate(self, x, predict):return tf.nn.sigmoid(x)值得提出的是,输出层,也就是costlayer的处理,把损失计算看成最后一层的激活方法,这个由于tensorflow的内置梯度计算,现在相当于forward pass增加了一步:
# Cost Layersclass CostLayer(Layer):def _activate(self, x, y):passdef calculate(self, y, y_pred):return self._activate(y.astype(np.float32), y_pred)class CrossEntropy(CostLayer):def _activate(self, x, y):return tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=x, labels=y))一个网络我们需要什么,至少需要2个变量,一是存放所有layers,而是存放所有的weights。
class NNBase:def __init__(self):# 一个NN是由各个layers构成,这里存放所有layers的信息,# 每个layers包含shape和weightsself._layers = []# 优化器是什么self._optimizer = None# 当前layer神经元的个数self._current_dimension = 0# data setsself._tfx = self._tfy = None# 把每一层的权重信息更新到总的列表self._tf_weights, self._tf_bias = [], []self._cost = self._y_pred = None self._train_step = None首先添加layer的过程是在干什么,没有想象的复杂:他基本干两件事,更新self._layers和self._tf_weights。
注意的structure都只是shape而已。
首先上述只是NN的一个基类,还有一些精心设计的网络模块化了,完整版的神经网络就叫做 NNDist,是在基类基础上完成的,其次训练是在会话里进行的。
class NNDist(NNBase):def __init__(self):NNBase.__init__(self)self._sess = tf.Session()def _get_prediction(self,x):with self._sess.as_default():# 将字符串str当成有效的表达式来求值并返回计算结果return self._get_rs(x).eval(feed_dict={self._tfx:x})def predict_classes(self, x):x = np.array(x)return np.argmax(self._get_prediction(x), axis=1)def fit(self, x=None, y=None, lr=0.001, epoch=10):# 记录的是结构用的 Optimizerself._optimizer = Adam(lr)# build graphself._tfx = tf.placeholder(tf.float32, shape=[None, x.shape[1]])self._tfy = tf.placeholder(tf.float32, shape=[None, y.shape[1]])with self._sess.as_default() as sess:self._cost = self._get_rs(self._tfx, self._tfy)self._y_pred = self._get_rs(self._tfx)self._train_step = self._optimizer.minimize(self._cost)sess.run(tf.global_variables_initializer())# trainfor counter in range(epoch):# 这种用法有点奇怪啊self._train_step.run(feed_dict={self._tfx: x, self._tfy: y})def evaluate(self, x, y):y_pred = self.predict_classes(x)y_arg = np.argmax(y, axis=1)print("Acc: {:8.6}".format(np.sum(y_arg == y_pred) / float(len(y_arg))))