2017-09-08 3 views
0

La question sur le tableau d'écrasement utilisant h5py n'a pas résolu mon problème. Je souhaite modifier les valeurs de tableau d'un modèle VGG16.Comment modifier les fichiers h5 avec h5py?

f = h5py.File('C:/Users/yash/.keras/models/vgg16_weights_tf_dim_ordering_tf_kernels_2.h5', mode = 'a') 
ab = list(h5py.AttributeManager.keys(f)) 
print(list(f.attrs.keys())) 
print(ab) 

Le code ci-dessus retours:

['layer_names'] 


['block1_conv1', 'block1_conv2', 'block1_pool', 'block2_conv1', 'block2_conv2', 'block2_pool', 'block3_conv1', 'block3_conv2', 'block3_conv3', 
'block3_pool', 'block4_conv1', 'block4_conv2', 'block4_conv3', 'block4_pool', 
'block5_conv1', 'block5_conv2', 'block5_conv3', 'block5_pool', 'fc1', 'fc2', 

'flatten', 'predictions'] 

Après avoir utilisé ce code: print(f.attrs['layer_names'])

Je reçois le texte suivant:

[b'block1_conv1' b'block1_conv2' b'block1_pool' b'block2_conv1' 
b'block2_conv2' b'block2_pool' b'block3_conv1' b'block3_conv2' 
b'block3_conv3' b'block3_pool' b'block4_conv1' b'block4_conv2' 
b'block4_conv3' b'block4_pool' b'block5_conv1' b'block5_conv2' 
b'block5_conv3' b'block5_pool' b'flatten' b'fc1' b'fc2' b'predictions'] 

Comment puis-je modifier les valeurs qui sont contenu dans le f.attrs['layer_names']? Je ne suis pas en mesure de les éditer principalement parce que l'utilisation: print(f.attrs['layer_names/block1_conv1']) renvoie une erreur.

Il existe une matrice de pondération et de polarisation à l'intérieur de chaque bloc (n) _conv (n).

Je veux changer ces valeurs. Je le fais en python 3, et aucune documentation ne m'a aidé à éditer ces valeurs. La plupart du temps parce que je ne peux pas y accéder sans utiliser ce code:

layer = h5py.AttributeManager.get(f, key = str(layerstringlist[i])) 
nplayer = np.asarray(list(layer)) 

layerstringlist est une liste de cette manière:

['block1_conv1/block1_conv1_W_1:0', 'block1_conv1/block1_conv1_b_1:0', ..... 
'predictions/predictions_W_1:0', 'predictions/predictions_b_1:0'] 

Cela renvoie correctement, mais je ne peux pas enregistrer le fichier h5 modifié parce que je ne sais pas comment le référencer en python 3.

Merci d'avance!

+0

Vous ne pouvez pas accéder aux choses avec 'f.attrs ['layer_names'] [0]', 'f.attrs ['layer_names'] [1]' etc? – Evert

+0

Je l'ai essayé. f.attrs ['layer_names'] [0] [:] renvoie b'block1_conv1 '. Fondamentalement, c'est une liste, qui est indexée en utilisant le [0]. J'ai besoin d'accéder au groupe à l'intérieur de 'block1_conv1' pour pouvoir utiliser cette matrice et l'éditer. Des conseils? – Mathbreaker

+0

La chaîne est une séquence d'octets donc oui, vous voyez la valeur (ASCII) du caractère à cette position (107 pour 'c'). Mais en effet, cela ne vous aide pas, car il accède uniquement aux noms des couches, pas à leurs données. – Evert

Répondre

0

Je ne l'ai pas vu l'utilisation de AttributeManager avant, peut-être parce que la documentation décourage son utilisation, http://docs.h5py.org/en/latest/high/attr.html#reference

Avec un fichier laissé par d'autres tests si je reçois:

In [480]: list(h5py.AttributeManager.keys(f)) 
Out[480]: ['agroup', 'agroup1', 'agroup2', 'arr'] 
In [481]: list(f.attrs.keys()) 
Out[481]: [] 
In [482]: list(f.keys()) 
Out[482]: ['agroup', 'agroup1', 'agroup2', 'arr'] 

Dans ce cas, Je n'ai attribué aucun attribut au fichier, donc f.attrs.keys() est vide. Il semble que votre fichier possède un attribut, "layer_names". Sa valeur est une liste de noms, que vous listez avec print(f.attrs['layer_names']).

Le AttributeManager répertorie les groupes et les ensembles de données, pas le attrs. J'ai la même liste avec f.keys().

Vous devriez être un accès de ces groupes ou ensembles de données avec:

f['block1_conv1'] 

Si cela est un groupe dont vous avez besoin pour indexer en bas une autre couche. S'il est un ensemble de données, lire et écrire comme décrit dans http://docs.h5py.org/en/latest/high/dataset.html#reading-writing-data

Je ne pense pas que la liste f.attrs['layer_names'] est d'aucune utilité pour vous, car il a les mêmes informations que la liste `(f.keys()) .


Sur la base de votre commentaire, f['block1_conv1'] est un groupe, avec plusieurs ensembles de données contient. Ce sont des moyens équivalents d'indexation d'un ensemble:

f['block1_conv1/block1_conv1_W_1:0'] 
f['block1_conv1']['block1_conv1_W_1:0'] 

Dans mon fichier de test

In [483]: f['arr'] 
Out[483]: <HDF5 dataset "arr": shape (3,), type "|V31"> 

Je peux charger l'ensemble de données dans la mémoire comme un tableau avec value ou [:]:

In [485]: f['arr'].value 
Out[485]: 
array([(123, 1, 1, 1, 1, 1, 1, 1), ( 1, 1, 1, 1, 1, 1, 1, 1), 
     ( 1, 1, 1, 1, 1, 1, 1, 1)], 
     dtype=[('Status', '<u8'), ('Segments', '<u4'), ('Characterized', '<u4'), ('More_Segments', '<u4'), ('ID', '<i4'), ('Releases', '<u2'), ('Type', 'u1'), ('Track', '<i4')]) 
In [486]: f['arr'][:] 
Out[486]: 
array([(123, 1, 1, 1, 1, 1, 1, 1), ( 1, 1, 1, 1, 1, 1, 1, 1), 
     ( 1, 1, 1, 1, 1, 1, 1, 1)], 
     dtype=[('Status', '<u8'), ('Segments', '<u4'), ('Characterized', '<u4'), ('More_Segments', '<u4'), ('ID', '<i4'), ('Releases', '<u2'), ('Type', 'u1'), ('Track', '<i4')]) 

(Désolé, cet exemple est un tableau structuré complexe.)

Je peux modifier les valeurs de cet ensemble de données comme je modifier un tableau du même type et la forme

In [487]: f['arr']['Status'] 
Out[487]: array([123, 1, 1], dtype=uint64) 
In [488]: f['arr']['Status'] = [1,2,3] 

Je ne peux pas le remplacer. f['arr'] = np.arange(10) me donne une erreur (le nom existe déjà). f['arr'][:] = np.arange(10) donne une erreur différente (à propos des formes incompatibles).

Je pourrais créer un nouvel ensemble de données avec un nom différent

In [492]: f.create_dataset('newarray', np.arange(10)) 
Out[492]: <HDF5 dataset "newarray": shape (0, 1, 2, 3, 4, 5, 6, 7, 8, 9), type "<f4"> 
In [493]: list(f.keys()) 
Out[493]: ['agroup', 'agroup1', 'agroup2', 'arr', 'newarray'] 

Je peux supprimer un ensemble de données avec:

In [494]: del f['newarray'] 
In [495]: list(f.keys()) 
Out[495]: ['agroup', 'agroup1', 'agroup2', 'arr'] 

et définir un nouveau avec le même nom avec:

In [500]: f.create_dataset('newarray', data=np.ones((3,4))) 
Out[500]: <HDF5 dataset "newarray": shape (3, 4), type "<f8"> 
+0

Cela fonctionne. f ['block1_conv1/block1_conv1_W_1: 0'] renvoie un jeu de données qui, une fois converti en liste, me donne la matrice que je voulais. Ma question est, comment puis-je changer cette matrice à un autre tableau numpy? (Je veux commettre le changement dans le fichier h5 à la fin) La documentation a rendu les choses plus compliquées pour moi, donc je vous le demande directement. Merci! – Mathbreaker

+0

J'ai ajouté quelques exemples d'accès et de modification de jeux de données. – hpaulj

+0

J'ai vu ce que vous avez dit, j'ai essayé: 'remplacer = np.zeros (forme = np.asarray (liste (f ['block1_conv1/block1_conv1_W_1: 0'])).forme) ' ' f ['block1_conv1/block1_conv1_W_1: 0'] = remplacer' Il me donne: Impossible de créer un lien (le nom existe déjà). Donc la seule façon pour moi de faire ceci est de supprimer cette référence spécifique, et créer une nouvelle référence: 'f.create_dataset ('block1_conv1/block1_conv1_W_1: 0', remplacer)' après la suppression de cet objet HDF5 oui? – Mathbreaker