tensorflow 常用函数和需要注意的地方

1 tf.add_to_collection

  • tf.add_to_collection(‘list_name’, element):将元素element添加到列表list_name中
  • tf.get_collection(‘list_name’):返回名称为list_name的列表
  • tf.add_n(list):将列表元素相加并返回
import tensorflow as tf
tf.add_to_collection('losses', tf.constant(2.2))
tf.add_to_collection('losses', tf.constant(3.))
with tf.Session() as sess:
    print(sess.run(tf.get_collection('losses')))
    print(sess.run(tf.add_n(tf.get_collection('losses'))

结果:
[2.2, 3.0]
5.2
注意:
使用tf.add_n对列表元素进行相加时,列表内元素类型必须一致,否则会报错。

2 集合

函数集合意义
tf.global_variables()GLOBAL_VARIABLES存储和读取checkpoints时,使用其中所有变量跨设备全局变量集合
tf.trainable_variables()TRAINABLE_VARIABLES训练时,更新其中所有变量存储需要训练的模型参数的变量集合
tf.moving_average_variables()MOVING_AVERAGE_VARIABLESExponentialMovingAverage对象会生成此类变量实用指数移动平均的变量集合
tf.local_variables()LOCAL_VARIABLES在global_variables()之外,需要用tf.init_local_variables()初始化进程内本地变量集合
tf.model_variables()MODEL_VARIABLESKey to collect model variables defined by layers.进程内存储的模型参数的变量集合
.QUEUE_RUNNERS并非存储variables,存储处理输入的QueueRunner
.SUMMARIES并非存储variables,存储日志生成相关张量

3 tf.squeeze

该函数返回一个张量,这个张量是将原始input中所有维度为1的那些维都删掉的结果
axis可以用来指定要删掉的为1的维度,此处要注意指定的维度必须确保其是1,否则会报错,axis的参数可以是列表或整数

squeeze(
    input,
    axis=None,
    name=None,
    squeeze_dims=None
)

4 tf.meshgrid

meshgrid用于从数组a和b产生网格。生成的网格矩阵A和B大小是相同的。它也可以是更高维的。用法: [A,B]=Meshgrid(a,b),生成size(b)Xsize(a)大小的矩阵A和B。它相当于a从一行重复增加到size(b)行,把b转置成一列再重复增加到size(a)列
注意:生成的矩阵A,B的尺寸是相同的,size(b)xsize(a),同时A,B二者生成的值相互独立

a=[0,5,10]
b=[0,5,15,20,25]
A,B=tf.meshgrid(a,b)
with tf.Session() as sess:
print (A.eval())
print (B.eval())
'''
结果
[[ 0 5 10]
[ 0 5 10]
[ 0 5 10]
[ 0 5 10]
[ 0 5 10]]


[[ 0 0 0]
[ 5 5 5]
[15 15 15]
[20 20 20]
[25 25 25]]
'''

这里的A,B可以是多维的

a = np.arange(4)
b = np.tile(np.expand_dims(a, 0),[4, 1])

aa, bb = np.meshgrid(a,b)
print(aa)
print(bb)
'''
output:
[[0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]]


[[0 0 0 0]
 [1 1 1 1]
 [2 2 2 2]
 [3 3 3 3]
 [0 0 0 0]
 [1 1 1 1]
 [2 2 2 2]
 [3 3 3 3]
 [0 0 0 0]
 [1 1 1 1]
 [2 2 2 2]
 [3 3 3 3]
 [0 0 0 0]
 [1 1 1 1]
 [2 2 2 2]
 [3 3 3 3]]
'''

其实原理一样,此时aa.shape=[B元素个数,len(a)] aa.shape==bb.shape

5 tf.slice()

函数:tf.slice(inputs, begin, size, name)

作用:从列表、数组、张量等对象中抽取一部分数据

begin和size是两个多维列表,他们共同决定了要抽取的数据的开始和结束位置

begin表示从inputs的哪几个维度上的哪个元素开始抽取
size表示在inputs的各个维度上抽取的元素个数

若begin[]或size[]中出现-1,表示抽取对应维度上的所有元素

6 tf.where()

tf.where(
condition,
x=None,
y=None,
name=None
)有两种用法

*如果x,y是空,则返回condition中值是TRUE的索引
举个例子:

a = np.array([1, 2, 1, 2, 1, 1, 2])
b = tf.reshape(tf.where(tf.equal(a, 1)), [-1])
with tf.Session() as sess:
    print(b.eval())
  #output:
  #[0 2 4 5]

*如果x,y不是空,则其中x,y均为尺寸一致的tensor,作用是将a中对应input中true的位置的元素值不变,其余元素进行替换,替换成y中对应位置的元素值,下面使用代码来说明:

a=np.array([[1,0,0],[0,1,1]])
a1=np.array([[3,2,3],[4,5,6]])
with tf.Session() as sess:

    print(sess.run(tf.equal(a,1)))
    print(sess.run(tf.where(tf.equal(a, 1), a1, 1 - a1)))

    '''
    [[ True False False]
    [False  True  True]]

    [[ 3 -1 -2]
     [-3  5  6]]
 '''

7 输出tensorflow ckpt文件节点名

from tensorflow.python import pywrap_tensorflow import os checkpoint_path = MODEL_FILE_CKPT reader = pywrap_tensorflow.NewCheckpointReader(checkpoint_path) var_to_shape_map = reader.get_variable_to_shape_map() for key in var_to_shape_map: print("tensor_name: ", key)

8 tf.image.crop_and_resize()

tf.image.crop_and_resize(
image,
boxes,
box_ind,
crop_size,
method=‘bilinear’,
extrapolation_value=0,
name=None
)

  • default_image_size: 张量,[batch,w,h,c]必须是下列类型之一:uint8,uint16,int8,int16,int32,int64,half,float32,float64; 注意:每张图片的尺寸必须相同

  • boxes:指需要划分的区域,输入格式为 [[ymin,xmin,ymax,xmax]] (要注意!这是一个二维列表)。官网在这里讲了一大段,看着简直头晕,大概意思是分了两种情况,一种是超出1另一种就是不超出1的。先将输入值范围为0–1的情况,这里其实是这样:
    设crop的区域坐标为 [ y1,x1,y2,x2 ],那么想得到相应正确的crop图形就一定要归!一!化!,即图片长度为 [ W,H ],则实际输入的boxes为 [ y1/H,x1/W,y2/H,x2/W ]。
    那超出1的范围是个啥意思咧?程序将为你自动补齐的意思,我试了几次都是直接用空白补齐,不知道大家有没有不一样的结果,注意奥!你的范围要是全部超出1,那就稳稳当当是个黑色框了,因为超出1根据归一化截取不到图片任何内容啦!

  • box_ind,就是boxes每一个对应的在batch中的标号,比如说,batch=2,len(boxes)是5,则假设一种对应关系,box_ind=[0,1,1,0,1],即是boxes第一个[ymin,xmin,ymax,xmax]属于第一张图片,boxes第二个[ymin,xmin,ymax,xmax]属于第二张图片,boxes第三个属于第二张图片。

  • crop_size:这个参数就可想而知啦,本来这就是我用这个函数的原因,输入一个大小即可,可以忽视通道数量这些

import numpy as np
import tensorflow as tf

import matplotlib.pyplot as plt
import cv2
img = cv2.imread('timg.jpg')

img1 = cv2.resize(img, (224, 224))
imgs = np.array([img1,img1])
shape = img1.shape

a = tf.image.crop_and_resize(imgs,[[0.5,0.5,0.6,0.2],[0.5,0.5,1.3,0.9],[0.5,0.5,1.3,0.9]],
                             box_ind=[0,1,1],crop_size=(100,100))
sess = tf.Session()
b = a.eval(session = sess)
print(b.shape)
#输出:(3, 100, 100, 3)

9 tensorflow关于"=="的坑

在目标检测的很多代码里都会有这样的代码

max_iou = tf.reduce_max(iou, axis=-1, keep_dims=True)
max_mask = tf.cast(iou>=max_iou, dtype=tf.float32)

max_iou是最后一维度的最大值,max_mask是将最大值位置标记成True例如
iou=[1,2]
max_iou = 2
max_mask = [False,True]
注意:这里的’>=‘不能换成’‘因为在tensorflow中,’‘是比较两个tensor的,而不是比较两个数值,比较数值是否相等要用tf.equal函数,而’>='则是比较两个tensor的数值大小。
例如:

a = tf.constant([1,2])
max = tf.reduce_max(a)
c = (a==max)
print(c) #false
d = (a>=max)
e = tf.equal(a,max)
with tf.Session() as sess:
  print(d.eval()) #[True,False]
  print(e.eval()) #[True,False]

总而言之,’==‘是用来比较两个tensor是否相同,’>='是用来比较数值大小的,比较两个tensor值是否相同要用tf.equal*

10 tensorflow 常用三种优化器

第一种和第二种需要自行设定learning_decay,否则有可能不会收敛,第三种只需要设定初始learning_rate即可

tf.train.GradientDescentOptimizer

    __init__(
        learning_rate,
        use_locking=False,
        name='GradientDescent'
    )
  • learning_rate: (学习率)张量或者浮点数
  • use_locking: 为True时锁定更新
  • name: 梯度下降名称,默认为"GradientDescent"

tf.train.MomentumOptimizer

其中, 即momentum,表示要在多大程度上保留原来的更新方向,这个值在0-1之间,在训练开始时,由于梯度可能会很大,所以初始值一般选为0.5;当梯度不那么大时,改为0.9。 是学习率,即当前batch的梯度多大程度上影响最终更新方向,跟普通的SGD含义相同。

__init__(
    learning_rate,
    momentum,
    use_locking=False,
    name='Momentum',
    use_nesterov=False
)
  • learning_rate: (学习率)张量或者浮点数
  • momentum: (动量)张量或者浮点数
  • use_locking: 为True时锁定更新
  • name: 梯度下降名称,默认为 “Momentum”.
  • use_nesterov: 为True时,使用 Nesterov

tf.train.AdamOptimizer

__init__(
    learning_rate=0.001,
    beta1=0.9,
    beta2=0.999,
    epsilon=1e-08,
    use_locking=False,
    name='Adam'
)
<think>好的,我现在要帮用户解答关于TensorFlow.js中可用的损失函数及其使用方法的问题。首先,我需要确认用户的问题范围。用户明确提到了TensorFlow.js,所以需要专注于JavaScript版本的TensorFlow,而不是Python的TensorFlow。这点很重要,因为不同版本可能有不同的实现API。 接下来,用户需要的是损失函数的列表以及它们的使用方法。我应该先回忆或查找TensorFlow.js官方文档中提到的损失函数。常见的损失函数包括均方误差(MSE)、绝对误差(MAE)、二元交叉熵、分类交叉熵等。需要确保这些在TensorFlow.js中确实存在,并且用法正确。 然后,我需要考虑如何组织这些信息。用户可能需要一个清晰的列表,每个损失函数的名称、数学表达式、适用场景以及代码示例。同时,根据用户提供的系统级指令,数学表达式需要用行内格式$...$,独立公式用$$...$$。例如,均方误差的公式是$\text{MSE} = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2$,而交叉熵可能需要更复杂的表达式。 另外,用户要求生成相关问题,我需要根据内容提出几个相关的问题,比如如何自定义损失函数,或者损失函数的选择对模型的影响等。这些问题应该与用户的问题紧密相关,帮助他们进一步学习。 还要注意引用部分。用户提供的引用中有三个,其中引用[1]提到TensorFlow.js在Node.js中的环境支持,引用[2]讨论的是TensorFlow 2中的自定义损失函数,可能TensorFlow.js的自定义方法有相似之处,但需要确认。引用[3]是关于安装包列表,可能不太相关,但可能涉及模型优化或其他工具包中的损失函数。需要合理引用这些内容,例如在讨论自定义损失函数时,可以引用[2]。 我需要确保所有的代码示例都是TensorFlow.js的语法,而不是Python的。例如,使用tf.losses.meanSquaredError而不是Keras的MSE。同时,代码示例要正确,比如如何计算损失,如何在模型编译时指定损失函数。 可能还需要提醒用户注意TensorFlow.jsTensorFlow的不同之处,比如API名称可能稍有不同,或者某些高级损失函数可能在JS版本中不可用。例如,稀疏分类交叉熵可能在TensorFlow.js中有不同的实现方式或名称。 最后,检查是否符合所有系统级指令:使用正确的中文,数学表达式格式正确,代码块使用正确的语法高亮,生成相关问题,并在适当的地方添加引用标记。例如,在提到自定义损失函数时,引用[2]中的内容,虽然它是关于TensorFlow 2的,但可能原理相通,可以指出参考类似的方法。</think>### TensorFlow.js 损失函数列表及使用方法 在 TensorFlow.js 中,损失函数用于衡量模型预测值与真实值之间的差异,是训练神经网络的核心组件。以下是常用损失函数及其用法: --- #### 1. **均方误差(Mean Squared Error, MSE)** - **数学表达式**: $$\text{MSE} = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2$$ - **适用场景**:回归任务(如房价预测)。 - **代码示例**: ```javascript const model = tf.sequential({ layers: [ tf.layers.dense({ units: 1, inputShape: [1] }) ] }); model.compile({ optimizer: 'sgd', loss: tf.losses.meanSquaredError // 直接调用内置函数 }); ``` --- #### 2. **二元交叉熵(Binary Crossentropy)** - **数学表达式**: $$\text{BCE} = -\frac{1}{n}\sum_{i=1}^{n}\left(y_i \log(\hat{y}_i) + (1-y_i)\log(1-\hat{y}_i)\right)$$ - **适用场景**:二分类任务(如垃圾邮件检测)。 - **代码示例**: ```javascript model.compile({ optimizer: 'adam', loss: 'binaryCrossentropy' // 使用字符串别名 }); ``` --- #### 3. **分类交叉熵(Categorical Crossentropy)** - **数学表达式**: $$\text{CCE} = -\sum_{i=1}^{C} y_i \log(\hat{y}_i)$$ 其中 $C$ 为类别数。 - **适用场景**:多分类任务(如手写数字识别)。 - **代码示例**: ```javascript model.compile({ optimizer: 'rmsprop', loss: tf.losses.softmaxCrossEntropy // 需配合 Softmax 激活 }); ``` --- #### 4. **绝对误差(Mean Absolute Error, MAE)** - **数学表达式**: $$\text{MAE} = \frac{1}{n}\sum_{i=1}^{n}|y_i - \hat{y}_i|$$ - **适用场景**:对异常值敏感的回归任务。 - **代码示例**: ```javascript model.compile({ optimizer: 'adam', loss: tf.metrics.meanAbsoluteError }); ``` --- #### 5. **Huber 损失(Huber Loss)** - **数学表达式**: $$ L_\delta(y, \hat{y}) = \begin{cases} \frac{1}{2}(y - \hat{y})^2 & \text{若 } |y - \hat{y}| \leq \delta \\ \delta |y - \hat{y}| - \frac{1}{2}\delta^2 & \text{否则} \end{cases} $$ - **适用场景**:结合 MSE MAE 的优点,适用于鲁棒回归。 - **代码示例**: ```javascript const huberLoss = (yTrue, yPred) => { const delta = 1.0; const error = yTrue.sub(yPred); const isSmallError = tf.abs(error).lessEqual(delta); const squaredLoss = error.square().mul(0.5); const linearLoss = tf.abs(error).mul(delta).sub(tf.scalar(0.5 * delta * delta)); return tf.where(isSmallError, squaredLoss, linearLoss).mean(); }; model.compile({ optimizer: 'sgd', loss: huberLoss }); ``` --- #### 6. **自定义损失函数** 通过函数定义实现复杂逻辑,例如带权重的损失函数[^2]: ```javascript function customLoss(weights) { return (yTrue, yPred) => { const error = yTrue.sub(yPred).square(); return error.mul(weights).mean(); }; } model.compile({ optimizer: 'adam', loss: customLoss(tf.tensor([0.5, 1.0])) }); ``` --- ### 注意事项 - **输入格式**:分类交叉熵需配合 `Softmax` 激活函数,标签需为 one-hot 编码。 - **性能优化**:在 Node.js 中可结合 TensorFlow C 绑定提升计算效率[^1]。 - **损失函数选择**:根据任务类型(回归/分类)数据分布选择合适函数。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值