日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

卷积层通道剪裁

發布時間:2023/11/28 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 卷积层通道剪裁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

卷積層通道剪裁
Pruner
classpaddleslim.prune.Pruner(criterion=“l1_norm”)
對卷積網絡的通道進行一次剪裁。剪裁一個卷積層的通道,是指剪裁該卷積層輸出的通道。卷積層的權重形狀為 [output_channel, input_channel, kernel_size, kernel_size] ,通過剪裁該權重的第一緯度達到剪裁輸出通道數的目的。
參數:
? criterion - 評估一個卷積層內通道重要性所參考的指標。目前僅支持 l1_norm 。默認為 l1_norm 。
返回: 一個Pruner類的實例
示例代碼:
from paddleslim.prune import Pruner
pruner = Pruner()
paddleslim.prune.Pruner.prune(program, scope, params, ratios, place=None, lazy=False, only_graph=False, param_backup=False, param_shape_backup=False)
對目標網絡的一組卷積層的權重進行裁剪。
參數:
? program(paddle.fluid.Program) - 要裁剪的目標網絡。更多關于Program的介紹請參考:Program概念介紹。
? scope(paddle.fluid.Scope) - 要裁剪的權重所在的 scope ,Paddle中用 scope 實例存放模型參數和運行時變量的值。Scope中的參數值會被 inplace 的裁剪。
? params(list) - 需要被裁剪的卷積層的參數的名稱列表。可以通過以下方式查看模型中所有參數的名稱:
for block in program.blocks:
for param in block.all_parameters():
print(“param: {}; shape: {}”.format(param.name, param.shape))
? ratios(list) - 用于裁剪 params 的剪切率,類型為列表。該列表長度必須與 params 的長度一致。
? place(paddle.fluid.Place) - 待裁剪參數所在的設備位置,可以是 CUDAPlace 或 CPUPlace 。Place概念介紹
? lazy(bool) - lazy 為True時,通過將指定通道的參數置零達到裁剪的目的,參數的 shape保持不變 ; lazy 為False時,直接將要裁的通道的參數刪除,參數的 shape 會發生變化。
? only_graph(bool) - 是否只裁剪網絡結構。在Paddle中,Program定義了網絡結構,Scope存儲參數的數值。一個Scope實例可以被多個Program使用,比如定義了訓練網絡的Program和定義了測試網絡的Program是使用同一個Scope實例的。 only_graph 為True時,只對Program中定義的卷積的通道進行剪裁; only_graph 為false時,Scope中卷積參數的數值也會被剪裁。默認為False。
? param_backup(bool) - 是否返回對參數值的備份。默認為False。
? param_shape_backup(bool) - 是否返回對參數 shape 的備份。默認為False。
返回:
? pruned_program(paddle.fluid.Program) - 被裁剪后的Program。
? param_backup(dict) - 對參數數值的備份,用于恢復Scope中的參數數值。
? param_shape_backup(dict) - 對參數形狀的備份。
示例:
執行以下示例代碼。
import paddle.fluid as fluid
from paddle.fluid.param_attr import ParamAttr
from paddleslim.prune import Pruner

def conv_bn_layer(input,
num_filters,
filter_size,
name,
stride=1,
groups=1,
act=None):
conv = fluid.layers.conv2d(
input=input,
num_filters=num_filters,
filter_size=filter_size,
stride=stride,
padding=(filter_size - 1) // 2,
groups=groups,
act=None,
param_attr=ParamAttr(name=name + “_weights”),
bias_attr=False,
name=name + “_out”)
bn_name = name + “_bn”
return fluid.layers.batch_norm(
input=conv,
act=act,
name=bn_name + ‘_output’,
param_attr=ParamAttr(name=bn_name + ‘_scale’),
bias_attr=ParamAttr(bn_name + ‘_offset’),
moving_mean_name=bn_name + ‘_mean’,
moving_variance_name=bn_name + ‘_variance’, )

main_program = fluid.Program()
startup_program = fluid.Program()

X X O X O

conv1–>conv2–>sum1–>conv3–>conv4–>sum2–>conv5–>conv6

| ^ | ^

|| |________|

X: prune output channels

O: prune input channels

with fluid.program_guard(main_program, startup_program):
input = fluid.data(name=“image”, shape=[None, 3, 16, 16])
conv1 = conv_bn_layer(input, 8, 3, “conv1”)
conv2 = conv_bn_layer(conv1, 8, 3, “conv2”)
sum1 = conv1 + conv2
conv3 = conv_bn_layer(sum1, 8, 3, “conv3”)
conv4 = conv_bn_layer(conv3, 8, 3, “conv4”)
sum2 = conv4 + sum1
conv5 = conv_bn_layer(sum2, 8, 3, “conv5”)
conv6 = conv_bn_layer(conv5, 8, 3, “conv6”)

place = fluid.CPUPlace()
exe = fluid.Executor(place)
scope = fluid.Scope()
exe.run(startup_program, scope=scope)
pruner = Pruner()
main_program, _, _ = pruner.prune(
main_program,
scope,
params=[“conv4_weights”],
ratios=[0.5],
place=place,
lazy=False,
only_graph=False,
param_backup=False,
param_shape_backup=False)

for param in main_program.global_block().all_parameters():
if “weights” in param.name:
print(“param name: {}; param shape: {}”.format(param.name, param.shape))
sensitivity
paddleslim.prune.sensitivity(program, place, param_names, eval_func, sensitivities_file=None, pruned_ratios=None)
計算網絡中每個卷積層的敏感度。每個卷積層的敏感度信息統計方法為:依次剪掉當前卷積層不同比例的輸出通道數,在測試集上計算剪裁后的精度損失。得到敏感度信息后,可以通過觀察或其它方式確定每層卷積的剪裁率。
參數:
? program(paddle.fluid.Program) - 待評估的目標網絡。更多關于Program的介紹請參考:Program概念介紹。
? place(paddle.fluid.Place) - 待分析的參數所在的設備位置,可以是 CUDAPlace 或 CPUPlace 。Place概念介紹
? param_names(list) - 待分析的卷積層的參數的名稱列表。可以通過以下方式查看模型中所有參數的名稱:
? eval_func(function) - 用于評估裁剪后模型效果的回調函數。該回調函數接受被裁剪后的 program 為參數,返回一個表示當前program的精度,用以計算當前裁剪帶來的精度損失。
? sensitivities_file(str) - 保存敏感度信息的本地文件系統的文件。在敏感度計算過程中,會持續將新計算出的敏感度信息追加到該文件中。重啟任務后,文件中已有敏感度信息不會被重復計算。該文件可以用 pickle 加載。
? pruned_ratios(list) - 計算卷積層敏感度信息時,依次剪掉的通道數比例。默認為 [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] 。
返回:
? sensitivities(dict) - 存放敏感度信息的dict,其格式為:
{“weight_0”:
{0.1: 0.22,
0.2: 0.33
},
“weight_1”:
{0.1: 0.21,
0.2: 0.4
}
}
其中, weight_0 是卷積層參數的名稱, sensitivities[‘weight_0’] 的 value 為剪裁比例, value 為精度損失的比例。
示例:
點擊 AIStudio 運行以下示例代碼。
import paddle
import numpy as np
import paddle.fluid as fluid
from paddle.fluid.param_attr import ParamAttr
from paddleslim.prune import sensitivity
import paddle.dataset.mnist as reader

def conv_bn_layer(input,
num_filters,
filter_size,
name,
stride=1,
groups=1,
act=None):
conv = fluid.layers.conv2d(
input=input,
num_filters=num_filters,
filter_size=filter_size,
stride=stride,
padding=(filter_size - 1) // 2,
groups=groups,
act=None,
param_attr=ParamAttr(name=name + “_weights”),
bias_attr=False,
name=name + “_out”)
bn_name = name + “_bn”
return fluid.layers.batch_norm(
input=conv,
act=act,
name=bn_name + ‘_output’,
param_attr=ParamAttr(name=bn_name + ‘_scale’),
bias_attr=ParamAttr(bn_name + ‘_offset’),
moving_mean_name=bn_name + ‘_mean’,
moving_variance_name=bn_name + ‘_variance’, )

main_program = fluid.Program()
startup_program = fluid.Program()

X X O X O

conv1–>conv2–>sum1–>conv3–>conv4–>sum2–>conv5–>conv6

| ^ | ^

|| |________|

X: prune output channels

O: prune input channels

image_shape = [1,28,28]
with fluid.program_guard(main_program, startup_program):
image = fluid.data(name=‘image’, shape=[None]+image_shape, dtype=‘float32’)
label = fluid.data(name=‘label’, shape=[None, 1], dtype=‘int64’)
conv1 = conv_bn_layer(image, 8, 3, “conv1”)
conv2 = conv_bn_layer(conv1, 8, 3, “conv2”)
sum1 = conv1 + conv2
conv3 = conv_bn_layer(sum1, 8, 3, “conv3”)
conv4 = conv_bn_layer(conv3, 8, 3, “conv4”)
sum2 = conv4 + sum1
conv5 = conv_bn_layer(sum2, 8, 3, “conv5”)
conv6 = conv_bn_layer(conv5, 8, 3, “conv6”)
out = fluid.layers.fc(conv6, size=10, act=“softmax”)

cost = fluid.layers.cross_entropy(input=out, label=label)

avg_cost = fluid.layers.mean(x=cost)

acc_top1 = fluid.layers.accuracy(input=out, label=label, k=1)

acc_top5 = fluid.layers.accuracy(input=out, label=label, k=5)

place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(startup_program)

val_reader = paddle.batch(reader.test(), batch_size=128)
val_feeder = feeder = fluid.DataFeeder(
[image, label], place, program=main_program)

def eval_func(program):

acc_top1_ns = []
for data in val_reader():acc_top1_n = exe.run(program,feed=val_feeder.feed(data),fetch_list=[acc_top1.name])acc_top1_ns.append(np.mean(acc_top1_n))
return np.mean(acc_top1_ns)

param_names = []
for param in main_program.global_block().all_parameters():
if “weights” in param.name:
param_names.append(param.name)
sensitivities = sensitivity(main_program,
place,
param_names,
eval_func,
sensitivities_file="./sensitive.data",
pruned_ratios=[0.1, 0.2, 0.3])
print(sensitivities)
merge_sensitive
paddleslim.prune.merge_sensitive(sensitivities)
合并多個敏感度信息。
參數:
? sensitivities(list | list) - 待合并的敏感度信息,可以是字典的列表,或者是存放敏感度信息的文件的路徑列表。
返回:
? sensitivities(dict) - 合并后的敏感度信息。其格式為:
{“weight_0”:
{0.1: 0.22,
0.2: 0.33
},
“weight_1”:
{0.1: 0.21,
0.2: 0.4
}
}
其中, weight_0 是卷積層參數的名稱, sensitivities[‘weight_0’] 的 value 為剪裁比例, value 為精度損失的比例。
示例:
from paddleslim.prune import merge_sensitive
sen0 = {“weight_0”:
{0.1: 0.22,
0.2: 0.33
},
“weight_1”:
{0.1: 0.21,
0.2: 0.4
}
}
sen1 = {“weight_0”:
{0.3: 0.41,
},
“weight_2”:
{0.1: 0.10,
0.2: 0.35
}
}
sensitivities = merge_sensitive([sen0, sen1])
print(sensitivities)
load_sensitivities
paddleslim.prune.load_sensitivities(sensitivities_file)
從文件中加載敏感度信息。
參數:
? sensitivities_file(str) - 存放敏感度信息的本地文件.
返回:
? sensitivities(dict) - 敏感度信息。
示例:
import pickle
from paddleslim.prune import load_sensitivities
sen = {“weight_0”:
{0.1: 0.22,
0.2: 0.33
},
“weight_1”:
{0.1: 0.21,
0.2: 0.4
}
}
sensitivities_file = “sensitive_api_demo.data”
with open(sensitivities_file, ‘wb’) as f:
pickle.dump(sen, f)
sensitivities = load_sensitivities(sensitivities_file)
print(sensitivities)
get_ratios_by_loss
paddleslim.prune.get_ratios_by_loss(sensitivities, loss)
根據敏感度和精度損失閾值計算出一組剪切率。對于參數 w , 其剪裁率為使精度損失低于 loss 的最大剪裁率。
參數:
? sensitivities(dict) - 敏感度信息。
? loss - 精度損失閾值。
返回:
? ratios(dict) - 一組剪切率。 key 是待剪裁參數的名稱。 value 是對應參數的剪裁率。
示例:
from paddleslim.prune import get_ratios_by_loss
sen = {“weight_0”:
{0.1: 0.22,
0.2: 0.33
},
“weight_1”:
{0.1: 0.21,
0.2: 0.4
}
}

ratios = get_ratios_by_loss(sen, 0.3)
print(ratios)

總結

以上是生活随笔為你收集整理的卷积层通道剪裁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。