[DL4J] Save&Load

[목차]

(0) 환경 설정 : DL4J 개발 환경 설정 및 예제 설명 (完)

(1) Data Iterator : 사용하고자 하는 데이터를 DL4J 에서 사용가능한 형태로 변환하는 작업 개발 필요

• Canova: The Rosetta Stone of Vectorization

• Spark

• Hadoop

• JDBC

Text ,CSV (完)

• Image

• Sound

• Video

(2) Net : 사용할 신경망의 형태가 어떤 것이 있는지 이해하고 선택, 활용 할 수 있어야 함
• Restricted Boltzmann machines (完)
• Convolutional nets (完)
• Recursive autoencoders (完)
• Recurrent nets: Long Short-Term Memory (LSTM) (including bi-directional LSTMs)
• Deep-belief networks
• Denoising and Stacked Denoising autoencoders
• Deep autoencoders

(3) Activation : Weight + Bias 결과 다음 적용할 함수 결정 (예 : SigMoid : Chap1 에서 설명한 것)

• ReLU (完)
• Leaky ReLU
• Tanh
• Sigmoid
• Hard Tanh
• Softmax
• Identity
• ELU: Exponential Linear Units
• Softsign
• Softplus

(4) Loss&Objective Functions : 일부 데이터를 누락함으로써 더 Robust 한 모델을 만들 수 있다.
• Reconstruction entropy
• Squared loss
• Mean squared error
• Multi-class cross entropy for classification
• Negative log likelihood
• RMSE_XENT

(5) Hyperparameters : 모든 Layer 에 공통적으로 적용되는 파라메터로 숙지 필요

• Dropout (random ommission of feature detectors to prevent overfitting)
• Sparsity (force activations of sparse/rare inputs)
• Adagrad (feature-specific learning-rate optimization)
• L1 and L2 regularization (weight decay)
• Weight transforms (useful for deep autoencoders)
• Probability distribution manipulation for initial weight generation
• Gradient normalization and clipping

(6) Event Listener & Result Anal : 분석 중간 발생하는 이벤트를 받아서 처리 및 결과에 대한 검증 및 비지니스 연동 등

(7) 모델 저장 및 로딩

• 매번 모든 데이터를 로딩하여 학습 시키는 것이 아니라, 모델 자체를 저장하고, 새로 발생하는 데이터만 학습 시킴으로써,

모델의 즉각적인 학습효과와 대량 데이터 처리에 따른 Performacne 문제를 해결 할수 있을 것으로 보임

http://deeplearning4j.org/modelpersistence

1. Save an Interoperable Vector of All Weights

– Neural Network 의 Cofiguration 값을 JSON 형태로 저장

– Neuron 의 모든 Weight 값과 Bias 값 등을 Binary 형태로 저장

– 아래는 모델을 저장하고 로딩하는 Sample 코드 이다, Code 상에는 File 로 되어 있지만,

Binary 형태로 변환하여 DB 에 Save & Load 를 하는 것도 가능할 것으로 보인다.

[Sample Code]

// 네트워크 파라메터 저장

try(DataOutputStream dos = new DataOutputStream(Files.newOutputStream(Paths.get("coefficients.bin")))){
Nd4j.write(net.params(),dos);
}

//네트워크 Configuration 저장
FileUtils.write(new File("conf.json"), net.getLayerWiseConfigurations().toJson());

//네트워크 Configuration 로딩
MultiLayerConfiguration confFromJson = MultiLayerConfiguration.fromJson(FileUtils.readFileToString(new File("conf.json")));

//네트워크 파라메터 로딩
INDArray newParams;
try(DataInputStream dis = new DataInputStream(new FileInputStream("coefficients.bin"))){
newParams = Nd4j.read(dis);
}

//저장된 정보로 네트워크 생성
MultiLayerNetwork savedNetwork = new MultiLayerNetwork(confFromJson);
savedNetwork.init();
savedNetwork.setParameters(newParams);

 

2. A Note on Updaters

데이터를 로딩한 후에 계속해서 Training 을 진행하고 싶다면, 네트워크의 부분만 저장하는 방법을 사용한다.

더 이상 Training 이 필요 없는 경우 더 이상 Save & Load 를 할 필요가 없다.

데이터 트레이닝에 momentum, AdaGrad and RMSProp와 같은 기법을 사용하는데, 이러한 기법들은

Trainging 의 이력을 남긴다. 이러한 이력 값 없이 그냥 파라메터를 저장하고 로딩할 경우 이후에 발생하는

Training 에서 데이터가 외곡될 가능성이 크다. 이러한 것을 방지하기 위해서 Update 를 저장하는 방법은

아래와 같다.

[Code Sample]

// Update 를 저장

try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("updater.bin"))){
oos.writeObject(model.getUpdater());
}

//Update 를 로드
org.deeplearning4j.nn.api.Updater updater;
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("updater.bin"))){
updater = (org.deeplearning4j.nn.api.Updater) ois.readObject();
}

//Update 값을 모델에 사용
model.setUpdater(updater);

 

3. Model Utils

– Model Util을 사용해서 모델을 업데이트하고 로드하는 예제

– 모델의 Save & Load 를 사용하여 한번에 대량의 데이터를 로딩하지 않음으로써,

서버의 부하를 줄이고, 지속적으로 발생하는 데이터를 학습시켜 모델의 정합성을

올리는 방식으로 사용할 수 있지 않을까 기대 함

/**
* Project utility class to save and load models and parameters.
*/
@Deprecated
public class ModelUtils {

private static final Logger log = LoggerFactory.getLogger(ModelUtils.class);

private ModelUtils(){}

public static void saveModelAndParameters(MultiLayerNetwork net, String basePath) {
String confPath = FilenameUtils.concat(basePath, net.toString()+"-conf.json");
String paramPath = FilenameUtils.concat(basePath, net.toString() + ".bin");
log.info("Saving model and parameters to {} and {} ...", confPath, paramPath);

// save parameters
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(paramPath));
Nd4j.write(net.params(), dos);
dos.flush();
dos.close();

// save model configuration
FileUtils.write(new File(confPath), net.conf().toJson());
} catch (IOException e) {
e.printStackTrace();
}
}

public static MultiLayerNetwork loadModelAndParameters(File confPath, String paramPath) {
log.info("Loading saved model and parameters...");
MultiLayerNetwork savedNetwork = null;
// load parameters
try {
MultiLayerConfiguration confFromJson = MultiLayerConfiguration.fromJson(FileUtils.readFileToString(confPath));
DataInputStream dis = new DataInputStream(new FileInputStream(paramPath));
INDArray newParams = Nd4j.read(dis);
dis.close();

// load model configuration
savedNetwork = new MultiLayerNetwork(confFromJson);
savedNetwork.init();
savedNetwork.setParams(newParams);
} catch (IOException e) {
e.printStackTrace();
}
return savedNetwork;
}

public static void saveLayerParameters(INDArray param, String paramPath) {
// save parameters for each layer
log.info("Saving parameters to {} ...", paramPath);

try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(paramPath));
Nd4j.write(param, dos);
dos.flush();
dos.close();
} catch(IOException e) {
e.printStackTrace();
}
}

public static Layer loadLayerParameters(Layer layer, String paramPath) {
// load parameters for each layer
String name = layer.conf().getLayer().getLayerName();
log.info("Loading saved parameters for layer {} ...", name);

try{
DataInputStream dis = new DataInputStream(new FileInputStream(paramPath));
INDArray param = Nd4j.read(dis);
dis.close();
layer.setParams(param);
} catch(IOException e) {
e.printStackTrace();
}

return layer;
}

public static void saveParameters(MultiLayerNetwork model, int[] layerIds, Map<Integer, String> paramPaths) {
Layer layer;
for(int layerId: layerIds) {
layer = model.getLayer(layerId);
if (!layer.paramTable().isEmpty()) {
ModelUtils.saveLayerParameters(layer.params(), paramPaths.get(layerId));
}
}
}

public static void saveParameters(MultiLayerNetwork model, String[] layerIds, Map<String, String> paramPaths) {
Layer layer;
for(String layerId: layerIds) {
layer = model.getLayer(layerId);
if (!layer.paramTable().isEmpty()) {
ModelUtils.saveLayerParameters(layer.params(), paramPaths.get(layerId));
}
}
}
public static MultiLayerNetwork loadParameters(MultiLayerNetwork model, int[] layerIds, Map<Integer, String> paramPaths) {
Layer layer;
for(int layerId: layerIds) {
layer = model.getLayer(layerId);
loadLayerParameters(layer, paramPaths.get(layerId));
}
return model;
}

public static MultiLayerNetwork loadParameters(MultiLayerNetwork model, String[] layerIds, Map<String, String> paramPaths) {
Layer layer;
for(String layerId: layerIds) {
layer = model.getLayer(layerId);
loadLayerParameters(layer, paramPaths.get(layerId));
}
return model;
}

public static Map<Integer, String> getIdParamPaths(MultiLayerNetwork model, String basePath, int[] layerIds){
Map<Integer, String> paramPaths = new HashMap<>();
for (int id : layerIds) {
paramPaths.put(id, FilenameUtils.concat(basePath, id + ".bin"));
}

return paramPaths;
}

public static Map<String, String> getStringParamPaths(MultiLayerNetwork model, String basePath, String[] layerIds){
Map<String, String> paramPaths = new HashMap<>();

for (String name : layerIds) {
paramPaths.put(name, FilenameUtils.concat(basePath, name + ".bin"));
}

return paramPaths;
}

public static String defineOutputDir(String modelType){
String tmpDir = System.getProperty("java.io.tmpdir");
String outputPath = File.separator + modelType + File.separator + "output";
File dataDir = new File(tmpDir,outputPath);
if (!dataDir.getParentFile().exists())
dataDir.mkdirs();
return dataDir.toString();

}

}

 

Leave a Reply

Your email address will not be published. Required fields are marked *