Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
torchani
Commits
e2e740d0
Unverified
Commit
e2e740d0
authored
Jul 31, 2018
by
Gao, Xiang
Committed by
GitHub
Jul 31, 2018
Browse files
completely decouple aev computer and neural networks (#40)
parent
ee31b752
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
176 additions
and
218 deletions
+176
-218
examples/energy_force.py
examples/energy_force.py
+5
-3
examples/model.py
examples/model.py
+13
-7
examples/nnp_training.py
examples/nnp_training.py
+2
-14
examples/training-benchmark.py
examples/training-benchmark.py
+10
-23
tests/test_aev.py
tests/test_aev.py
+10
-5
tests/test_batch.py
tests/test_batch.py
+5
-2
tests/test_benchmark.py
tests/test_benchmark.py
+24
-22
tests/test_energies.py
tests/test_energies.py
+6
-3
tests/test_ensemble.py
tests/test_ensemble.py
+7
-4
tests/test_forces.py
tests/test_forces.py
+6
-4
tests/test_ignite.py
tests/test_ignite.py
+7
-10
torchani/__init__.py
torchani/__init__.py
+3
-2
torchani/aev.py
torchani/aev.py
+53
-43
torchani/models/ani_model.py
torchani/models/ani_model.py
+12
-51
torchani/models/batch.py
torchani/models/batch.py
+1
-1
torchani/models/custom.py
torchani/models/custom.py
+4
-3
torchani/models/neurochem_atomic_network.py
torchani/models/neurochem_atomic_network.py
+4
-14
torchani/models/neurochem_nnp.py
torchani/models/neurochem_nnp.py
+4
-7
No files found.
examples/energy_force.py
View file @
e2e740d0
...
@@ -9,8 +9,10 @@ sae_file = os.path.join(path, '../torchani/resources/ani-1x_dft_x8ens/sae_linfit
...
@@ -9,8 +9,10 @@ sae_file = os.path.join(path, '../torchani/resources/ani-1x_dft_x8ens/sae_linfit
network_dir
=
os
.
path
.
join
(
path
,
'../torchani/resources/ani-1x_dft_x8ens/train'
)
# noqa: E501
network_dir
=
os
.
path
.
join
(
path
,
'../torchani/resources/ani-1x_dft_x8ens/train'
)
# noqa: E501
aev_computer
=
torchani
.
SortedAEV
(
const_file
=
const_file
,
device
=
device
)
aev_computer
=
torchani
.
SortedAEV
(
const_file
=
const_file
,
device
=
device
)
nn
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
,
derivative
=
True
,
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
aev_computer
.
device
)
from_
=
network_dir
,
ensemble
=
8
)
nn
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
.
species
,
from_
=
network_dir
,
ensemble
=
8
)
model
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
,
nn
)
shift_energy
=
torchani
.
EnergyShifter
(
sae_file
)
shift_energy
=
torchani
.
EnergyShifter
(
sae_file
)
coordinates
=
torch
.
tensor
([[[
0.03192167
,
0.00638559
,
0.01301679
],
coordinates
=
torch
.
tensor
([[[
0.03192167
,
0.00638559
,
0.01301679
],
...
@@ -23,7 +25,7 @@ coordinates = torch.tensor([[[0.03192167, 0.00638559, 0.01301679],
...
@@ -23,7 +25,7 @@ coordinates = torch.tensor([[[0.03192167, 0.00638559, 0.01301679],
requires_grad
=
True
)
requires_grad
=
True
)
species
=
[
'C'
,
'H'
,
'H'
,
'H'
,
'H'
]
species
=
[
'C'
,
'H'
,
'H'
,
'H'
,
'H'
]
energy
=
nn
(
coordinates
,
species
)
energy
=
model
((
species
,
coordinates
)
)
derivative
=
torch
.
autograd
.
grad
(
energy
.
sum
(),
coordinates
)[
0
]
derivative
=
torch
.
autograd
.
grad
(
energy
.
sum
(),
coordinates
)[
0
]
energy
=
shift_energy
.
add_sae
(
energy
,
species
)
energy
=
shift_energy
.
add_sae
(
energy
,
species
)
force
=
-
derivative
force
=
-
derivative
...
...
examples/model.py
View file @
e2e740d0
...
@@ -9,9 +9,8 @@ def celu(x, alpha):
...
@@ -9,9 +9,8 @@ def celu(x, alpha):
class
AtomicNetwork
(
torch
.
nn
.
Module
):
class
AtomicNetwork
(
torch
.
nn
.
Module
):
def
__init__
(
self
,
aev_computer
):
def
__init__
(
self
):
super
(
AtomicNetwork
,
self
).
__init__
()
super
(
AtomicNetwork
,
self
).
__init__
()
self
.
aev_computer
=
aev_computer
self
.
output_length
=
1
self
.
output_length
=
1
self
.
layer1
=
torch
.
nn
.
Linear
(
384
,
128
)
self
.
layer1
=
torch
.
nn
.
Linear
(
384
,
128
)
self
.
layer2
=
torch
.
nn
.
Linear
(
128
,
128
)
self
.
layer2
=
torch
.
nn
.
Linear
(
128
,
128
)
...
@@ -33,16 +32,23 @@ class AtomicNetwork(torch.nn.Module):
...
@@ -33,16 +32,23 @@ class AtomicNetwork(torch.nn.Module):
def
get_or_create_model
(
filename
,
benchmark
=
False
,
def
get_or_create_model
(
filename
,
benchmark
=
False
,
device
=
torchani
.
default_device
):
device
=
torchani
.
default_device
):
aev_computer
=
torchani
.
SortedAEV
(
benchmark
=
benchmark
,
device
=
device
)
aev_computer
=
torchani
.
SortedAEV
(
benchmark
=
benchmark
,
device
=
device
)
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
aev_computer
.
device
)
model
=
torchani
.
models
.
CustomModel
(
model
=
torchani
.
models
.
CustomModel
(
aev_computer
,
reducer
=
torch
.
sum
,
reducer
=
torch
.
sum
,
benchmark
=
benchmark
,
benchmark
=
benchmark
,
per_species
=
{
per_species
=
{
'C'
:
AtomicNetwork
(
aev_computer
),
'C'
:
AtomicNetwork
(),
'H'
:
AtomicNetwork
(
aev_computer
),
'H'
:
AtomicNetwork
(),
'N'
:
AtomicNetwork
(
aev_computer
),
'N'
:
AtomicNetwork
(),
'O'
:
AtomicNetwork
(
aev_computer
),
'O'
:
AtomicNetwork
(),
})
})
class
Flatten
(
torch
.
nn
.
Module
):
def
forward
(
self
,
x
):
return
x
.
flatten
()
model
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
,
model
,
Flatten
())
if
os
.
path
.
isfile
(
filename
):
if
os
.
path
.
isfile
(
filename
):
model
.
load_state_dict
(
torch
.
load
(
filename
))
model
.
load_state_dict
(
torch
.
load
(
filename
))
else
:
else
:
...
...
examples/nnp_training.py
View file @
e2e740d0
...
@@ -24,23 +24,11 @@ training, validation, testing = torchani.data.load_or_create(
...
@@ -24,23 +24,11 @@ training, validation, testing = torchani.data.load_or_create(
transform
=
[
shift_energy
.
dataset_subtract_sae
])
transform
=
[
shift_energy
.
dataset_subtract_sae
])
training
=
torchani
.
data
.
dataloader
(
training
,
batch_chunks
)
training
=
torchani
.
data
.
dataloader
(
training
,
batch_chunks
)
validation
=
torchani
.
data
.
dataloader
(
validation
,
batch_chunks
)
validation
=
torchani
.
data
.
dataloader
(
validation
,
batch_chunks
)
nnp
=
model
.
get_or_create_model
(
model_checkpoint
)
nnp
=
model
.
get_or_create_model
(
model_checkpoint
)
batch_nnp
=
torchani
.
models
.
BatchModel
(
nnp
)
class
Flatten
(
torch
.
nn
.
Module
):
def
__init__
(
self
,
model
):
super
(
Flatten
,
self
).
__init__
()
self
.
model
=
model
def
forward
(
self
,
*
input
):
return
self
.
model
(
*
input
).
flatten
()
batch_nnp
=
torchani
.
models
.
BatchModel
(
Flatten
(
nnp
))
container
=
torchani
.
ignite
.
Container
({
'energies'
:
batch_nnp
})
container
=
torchani
.
ignite
.
Container
({
'energies'
:
batch_nnp
})
optimizer
=
torch
.
optim
.
Adam
(
nnp
.
parameters
())
optimizer
=
torch
.
optim
.
Adam
(
nnp
.
parameters
())
trainer
=
ignite
.
engine
.
create_supervised_trainer
(
trainer
=
ignite
.
engine
.
create_supervised_trainer
(
container
,
optimizer
,
torchani
.
ignite
.
energy_mse_loss
)
container
,
optimizer
,
torchani
.
ignite
.
energy_mse_loss
)
evaluator
=
ignite
.
engine
.
create_supervised_evaluator
(
container
,
metrics
=
{
evaluator
=
ignite
.
engine
.
create_supervised_evaluator
(
container
,
metrics
=
{
...
...
examples/training-benchmark.py
View file @
e2e740d0
...
@@ -15,19 +15,7 @@ dataset = torchani.data.ANIDataset(
...
@@ -15,19 +15,7 @@ dataset = torchani.data.ANIDataset(
transform
=
[
shift_energy
.
dataset_subtract_sae
])
transform
=
[
shift_energy
.
dataset_subtract_sae
])
dataloader
=
torchani
.
data
.
dataloader
(
dataset
,
batch_chunks
)
dataloader
=
torchani
.
data
.
dataloader
(
dataset
,
batch_chunks
)
nnp
=
model
.
get_or_create_model
(
'/tmp/model.pt'
,
True
)
nnp
=
model
.
get_or_create_model
(
'/tmp/model.pt'
,
True
)
batch_nnp
=
torchani
.
models
.
BatchModel
(
nnp
)
class
Flatten
(
torch
.
nn
.
Module
):
def
__init__
(
self
,
model
):
super
(
Flatten
,
self
).
__init__
()
self
.
model
=
model
def
forward
(
self
,
*
input
):
return
self
.
model
(
*
input
).
flatten
()
batch_nnp
=
torchani
.
models
.
BatchModel
(
Flatten
(
nnp
))
container
=
torchani
.
ignite
.
Container
({
'energies'
:
batch_nnp
})
container
=
torchani
.
ignite
.
Container
({
'energies'
:
batch_nnp
})
optimizer
=
torch
.
optim
.
Adam
(
nnp
.
parameters
())
optimizer
=
torch
.
optim
.
Adam
(
nnp
.
parameters
())
...
@@ -53,14 +41,13 @@ def finalize_tqdm(trainer):
...
@@ -53,14 +41,13 @@ def finalize_tqdm(trainer):
start
=
timeit
.
default_timer
()
start
=
timeit
.
default_timer
()
trainer
.
run
(
dataloader
,
max_epochs
=
1
)
trainer
.
run
(
dataloader
,
max_epochs
=
1
)
elapsed
=
round
(
timeit
.
default_timer
()
-
start
,
2
)
elapsed
=
round
(
timeit
.
default_timer
()
-
start
,
2
)
print
(
'Radial terms:'
,
nnp
.
aev_computer
.
timers
[
'radial terms'
])
print
(
'Radial terms:'
,
nnp
[
1
].
timers
[
'radial terms'
])
print
(
'Angular terms:'
,
nnp
.
aev_computer
.
timers
[
'angular terms'
])
print
(
'Angular terms:'
,
nnp
[
1
].
timers
[
'angular terms'
])
print
(
'Terms and indices:'
,
nnp
.
aev_computer
.
timers
[
'terms and indices'
])
print
(
'Terms and indices:'
,
nnp
[
1
].
timers
[
'terms and indices'
])
print
(
'Combinations:'
,
nnp
.
aev_computer
.
timers
[
'combinations'
])
print
(
'Combinations:'
,
nnp
[
1
].
timers
[
'combinations'
])
print
(
'Mask R:'
,
nnp
.
aev_computer
.
timers
[
'mask_r'
])
print
(
'Mask R:'
,
nnp
[
1
].
timers
[
'mask_r'
])
print
(
'Mask A:'
,
nnp
.
aev_computer
.
timers
[
'mask_a'
])
print
(
'Mask A:'
,
nnp
[
1
].
timers
[
'mask_a'
])
print
(
'Assemble:'
,
nnp
.
aev_computer
.
timers
[
'assemble'
])
print
(
'Assemble:'
,
nnp
[
1
].
timers
[
'assemble'
])
print
(
'Total AEV:'
,
nnp
.
aev_computer
.
timers
[
'total'
])
print
(
'Total AEV:'
,
nnp
[
1
].
timers
[
'total'
])
print
(
'NN:'
,
nnp
.
timers
[
'nn'
])
print
(
'NN:'
,
nnp
[
2
].
timers
[
'forward'
])
print
(
'Total Forward:'
,
nnp
.
timers
[
'forward'
])
print
(
'Epoch time:'
,
elapsed
)
print
(
'Epoch time:'
,
elapsed
)
tests/test_aev.py
View file @
e2e740d0
...
@@ -11,15 +11,20 @@ N = 97
...
@@ -11,15 +11,20 @@ N = 97
class
TestAEV
(
unittest
.
TestCase
):
class
TestAEV
(
unittest
.
TestCase
):
def
setUp
(
self
,
dtype
=
torchani
.
default_dtype
):
def
setUp
(
self
,
dtype
=
torchani
.
default_dtype
):
self
.
aev
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
torch
.
device
(
'cpu'
))
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
torch
.
device
(
'cpu'
))
self
.
radial_length
=
aev_computer
.
radial_length
self
.
aev
=
torch
.
nn
.
Sequential
(
torchani
.
PrepareInput
(
aev_computer
.
species
,
aev_computer
.
device
),
aev_computer
)
self
.
tolerance
=
1e-5
self
.
tolerance
=
1e-5
def
_test_molecule
(
self
,
coordinates
,
species
,
expected_radial
,
def
_test_molecule
(
self
,
coordinates
,
species
,
expected_radial
,
expected_angular
):
expected_angular
):
species
=
self
.
aev
.
species_to_tensor
(
species
)
species
,
aev
=
self
.
aev
((
species
,
coordinates
))
aev
=
self
.
aev
((
coordinates
,
species
))
radial
=
aev
[...,
:
self
.
radial_length
]
radial
=
aev
[...,
:
self
.
aev
.
radial_length
]
angular
=
aev
[...,
self
.
radial_length
:]
angular
=
aev
[...,
self
.
aev
.
radial_length
:]
radial_diff
=
expected_radial
-
radial
radial_diff
=
expected_radial
-
radial
radial_max_error
=
torch
.
max
(
torch
.
abs
(
radial_diff
)).
item
()
radial_max_error
=
torch
.
max
(
torch
.
abs
(
radial_diff
)).
item
()
angular_diff
=
expected_angular
-
angular
angular_diff
=
expected_angular
-
angular
...
...
tests/test_batch.py
View file @
e2e740d0
...
@@ -21,8 +21,11 @@ if sys.version_info.major >= 3:
...
@@ -21,8 +21,11 @@ if sys.version_info.major >= 3:
ds
=
torchani
.
data
.
ANIDataset
(
path
,
chunksize
,
device
=
device
)
ds
=
torchani
.
data
.
ANIDataset
(
path
,
chunksize
,
device
=
device
)
loader
=
torchani
.
data
.
dataloader
(
ds
,
batch_chunks
)
loader
=
torchani
.
data
.
dataloader
(
ds
,
batch_chunks
)
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
device
)
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
device
)
nnp
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
)
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
batch_nnp
=
torchani
.
models
.
BatchModel
(
nnp
)
aev_computer
.
device
)
nnp
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
.
species
)
model
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
,
nnp
)
batch_nnp
=
torchani
.
models
.
BatchModel
(
model
)
for
batch_input
,
batch_output
in
itertools
.
islice
(
loader
,
10
):
for
batch_input
,
batch_output
in
itertools
.
islice
(
loader
,
10
):
batch_output_
=
batch_nnp
(
batch_input
).
squeeze
()
batch_output_
=
batch_nnp
(
batch_input
).
squeeze
()
self
.
assertListEqual
(
list
(
batch_output_
.
shape
),
self
.
assertListEqual
(
list
(
batch_output_
.
shape
),
...
...
tests/test_benchmark.py
View file @
e2e740d0
...
@@ -16,7 +16,7 @@ class TestBenchmark(unittest.TestCase):
...
@@ -16,7 +16,7 @@ class TestBenchmark(unittest.TestCase):
self
.
conformations
,
8
,
3
,
dtype
=
dtype
,
device
=
device
)
self
.
conformations
,
8
,
3
,
dtype
=
dtype
,
device
=
device
)
self
.
count
=
100
self
.
count
=
100
def
_testModule
(
self
,
module
,
asserts
):
def
_testModule
(
self
,
run_module
,
result_
module
,
asserts
):
keys
=
[]
keys
=
[]
for
i
in
asserts
:
for
i
in
asserts
:
if
'>='
in
i
:
if
'>='
in
i
:
...
@@ -36,57 +36,57 @@ class TestBenchmark(unittest.TestCase):
...
@@ -36,57 +36,57 @@ class TestBenchmark(unittest.TestCase):
keys
+=
[
i
[
0
].
strip
(),
i
[
1
].
strip
()]
keys
+=
[
i
[
0
].
strip
(),
i
[
1
].
strip
()]
else
:
else
:
keys
.
append
(
i
.
strip
())
keys
.
append
(
i
.
strip
())
self
.
assertEqual
(
set
(
module
.
timers
.
keys
()),
set
(
keys
))
self
.
assertEqual
(
set
(
result_
module
.
timers
.
keys
()),
set
(
keys
))
for
i
in
keys
:
for
i
in
keys
:
self
.
assertEqual
(
module
.
timers
[
i
],
0
)
self
.
assertEqual
(
result_
module
.
timers
[
i
],
0
)
old_timers
=
copy
.
copy
(
module
.
timers
)
old_timers
=
copy
.
copy
(
result_
module
.
timers
)
for
_
in
range
(
self
.
count
):
for
_
in
range
(
self
.
count
):
if
isinstance
(
module
,
torchani
.
aev
.
AEVComputer
):
run_module
((
self
.
species
,
self
.
coordinates
))
species
=
module
.
species_to_tensor
(
self
.
species
)
module
((
self
.
coordinates
,
species
))
else
:
module
(
self
.
coordinates
,
self
.
species
)
for
i
in
keys
:
for
i
in
keys
:
self
.
assertLess
(
old_timers
[
i
],
module
.
timers
[
i
])
self
.
assertLess
(
old_timers
[
i
],
result_
module
.
timers
[
i
])
for
i
in
asserts
:
for
i
in
asserts
:
if
'>='
in
i
:
if
'>='
in
i
:
i
=
i
.
split
(
'>='
)
i
=
i
.
split
(
'>='
)
key0
=
i
[
0
].
strip
()
key0
=
i
[
0
].
strip
()
key1
=
i
[
1
].
strip
()
key1
=
i
[
1
].
strip
()
self
.
assertGreaterEqual
(
self
.
assertGreaterEqual
(
module
.
timers
[
key0
],
module
.
timers
[
key1
])
result_
module
.
timers
[
key0
],
result_
module
.
timers
[
key1
])
elif
'<='
in
i
:
elif
'<='
in
i
:
i
=
i
.
split
(
'<='
)
i
=
i
.
split
(
'<='
)
key0
=
i
[
0
].
strip
()
key0
=
i
[
0
].
strip
()
key1
=
i
[
1
].
strip
()
key1
=
i
[
1
].
strip
()
self
.
assertLessEqual
(
self
.
assertLessEqual
(
module
.
timers
[
key0
],
module
.
timers
[
key1
])
result_
module
.
timers
[
key0
],
result_
module
.
timers
[
key1
])
elif
'>'
in
i
:
elif
'>'
in
i
:
i
=
i
.
split
(
'>'
)
i
=
i
.
split
(
'>'
)
key0
=
i
[
0
].
strip
()
key0
=
i
[
0
].
strip
()
key1
=
i
[
1
].
strip
()
key1
=
i
[
1
].
strip
()
self
.
assertGreater
(
self
.
assertGreater
(
module
.
timers
[
key0
],
module
.
timers
[
key1
])
result_
module
.
timers
[
key0
],
result_
module
.
timers
[
key1
])
elif
'<'
in
i
:
elif
'<'
in
i
:
i
=
i
.
split
(
'<'
)
i
=
i
.
split
(
'<'
)
key0
=
i
[
0
].
strip
()
key0
=
i
[
0
].
strip
()
key1
=
i
[
1
].
strip
()
key1
=
i
[
1
].
strip
()
self
.
assertLess
(
module
.
timers
[
key0
],
module
.
timers
[
key1
])
self
.
assertLess
(
result_module
.
timers
[
key0
],
result_module
.
timers
[
key1
])
elif
'='
in
i
:
elif
'='
in
i
:
i
=
i
.
split
(
'='
)
i
=
i
.
split
(
'='
)
key0
=
i
[
0
].
strip
()
key0
=
i
[
0
].
strip
()
key1
=
i
[
1
].
strip
()
key1
=
i
[
1
].
strip
()
self
.
assertEqual
(
module
.
timers
[
key0
],
module
.
timers
[
key1
])
self
.
assertEqual
(
result_module
.
timers
[
key0
],
old_timers
=
copy
.
copy
(
module
.
timers
)
result_module
.
timers
[
key1
])
module
.
reset_timers
()
old_timers
=
copy
.
copy
(
result_module
.
timers
)
self
.
assertEqual
(
set
(
module
.
timers
.
keys
()),
set
(
keys
))
result_module
.
reset_timers
()
self
.
assertEqual
(
set
(
result_module
.
timers
.
keys
()),
set
(
keys
))
for
i
in
keys
:
for
i
in
keys
:
self
.
assertEqual
(
module
.
timers
[
i
],
0
)
self
.
assertEqual
(
result_
module
.
timers
[
i
],
0
)
def
testAEV
(
self
):
def
testAEV
(
self
):
aev_computer
=
torchani
.
SortedAEV
(
aev_computer
=
torchani
.
SortedAEV
(
benchmark
=
True
,
dtype
=
self
.
dtype
,
device
=
self
.
device
)
benchmark
=
True
,
dtype
=
self
.
dtype
,
device
=
self
.
device
)
self
.
_testModule
(
aev_computer
,
[
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
self
.
device
)
run_module
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
)
self
.
_testModule
(
run_module
,
aev_computer
,
[
'terms and indices>radial terms'
,
'terms and indices>radial terms'
,
'terms and indices>angular terms'
,
'terms and indices>angular terms'
,
'total>terms and indices'
,
'total>terms and indices'
,
...
@@ -97,9 +97,11 @@ class TestBenchmark(unittest.TestCase):
...
@@ -97,9 +97,11 @@ class TestBenchmark(unittest.TestCase):
def
testANIModel
(
self
):
def
testANIModel
(
self
):
aev_computer
=
torchani
.
SortedAEV
(
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
self
.
dtype
,
device
=
self
.
device
)
dtype
=
self
.
dtype
,
device
=
self
.
device
)
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
self
.
device
)
model
=
torchani
.
models
.
NeuroChemNNP
(
model
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
,
benchmark
=
True
)
aev_computer
.
species
,
benchmark
=
True
)
self
.
_testModule
(
model
,
[
'forward>nn'
])
run_module
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
,
model
)
self
.
_testModule
(
run_module
,
model
,
[
'forward'
])
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
tests/test_energies.py
View file @
e2e740d0
...
@@ -14,13 +14,16 @@ class TestEnergies(unittest.TestCase):
...
@@ -14,13 +14,16 @@ class TestEnergies(unittest.TestCase):
def
setUp
(
self
,
dtype
=
torchani
.
default_dtype
,
def
setUp
(
self
,
dtype
=
torchani
.
default_dtype
,
device
=
torchani
.
default_device
):
device
=
torchani
.
default_device
):
self
.
tolerance
=
5e-5
self
.
tolerance
=
5e-5
self
.
aev_computer
=
torchani
.
SortedAEV
(
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
torch
.
device
(
'cpu'
))
dtype
=
dtype
,
device
=
torch
.
device
(
'cpu'
))
self
.
nnp
=
torchani
.
models
.
NeuroChemNNP
(
self
.
aev_computer
)
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
aev_computer
.
device
)
nnp
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
.
species
)
self
.
model
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
,
nnp
)
def
_test_molecule
(
self
,
coordinates
,
species
,
energies
):
def
_test_molecule
(
self
,
coordinates
,
species
,
energies
):
shift_energy
=
torchani
.
EnergyShifter
(
torchani
.
buildin_sae_file
)
shift_energy
=
torchani
.
EnergyShifter
(
torchani
.
buildin_sae_file
)
energies_
=
self
.
nnp
(
coordinates
,
species
).
squeeze
()
energies_
=
self
.
model
((
species
,
coordinates
)
).
squeeze
()
energies_
=
shift_energy
.
add_sae
(
energies_
,
species
)
energies_
=
shift_energy
.
add_sae
(
energies_
,
species
)
max_diff
=
(
energies
-
energies_
).
abs
().
max
().
item
()
max_diff
=
(
energies
-
energies_
).
abs
().
max
().
item
()
self
.
assertLess
(
max_diff
,
self
.
tolerance
)
self
.
assertLess
(
max_diff
,
self
.
tolerance
)
...
...
tests/test_ensemble.py
View file @
e2e740d0
...
@@ -19,15 +19,18 @@ class TestEnsemble(unittest.TestCase):
...
@@ -19,15 +19,18 @@ class TestEnsemble(unittest.TestCase):
n
=
torchani
.
buildin_ensemble
n
=
torchani
.
buildin_ensemble
prefix
=
torchani
.
buildin_model_prefix
prefix
=
torchani
.
buildin_model_prefix
aev
=
torchani
.
SortedAEV
(
device
=
torch
.
device
(
'cpu'
))
aev
=
torchani
.
SortedAEV
(
device
=
torch
.
device
(
'cpu'
))
ensemble
=
torchani
.
models
.
NeuroChemNNP
(
aev
,
ensemble
=
True
)
prepare
=
torchani
.
PrepareInput
(
aev
.
species
,
aev
.
device
)
ensemble
=
torchani
.
models
.
NeuroChemNNP
(
aev
.
species
,
ensemble
=
True
)
ensemble
=
torch
.
nn
.
Sequential
(
prepare
,
aev
,
ensemble
)
models
=
[
torchani
.
models
.
models
=
[
torchani
.
models
.
NeuroChemNNP
(
aev
,
ensemble
=
False
,
NeuroChemNNP
(
aev
.
species
,
ensemble
=
False
,
from_
=
prefix
+
'{}/networks/'
.
format
(
i
))
from_
=
prefix
+
'{}/networks/'
.
format
(
i
))
for
i
in
range
(
n
)]
for
i
in
range
(
n
)]
models
=
[
torch
.
nn
.
Sequential
(
prepare
,
aev
,
m
)
for
m
in
models
]
energy1
=
ensemble
(
coordinates
,
species
)
energy1
=
ensemble
(
(
species
,
coordinates
)
)
force1
=
torch
.
autograd
.
grad
(
energy1
.
sum
(),
coordinates
)[
0
]
force1
=
torch
.
autograd
.
grad
(
energy1
.
sum
(),
coordinates
)[
0
]
energy2
=
[
m
(
coordinates
,
species
)
for
m
in
models
]
energy2
=
[
m
(
(
species
,
coordinates
)
)
for
m
in
models
]
energy2
=
sum
(
energy2
)
/
n
energy2
=
sum
(
energy2
)
/
n
force2
=
torch
.
autograd
.
grad
(
energy2
.
sum
(),
coordinates
)[
0
]
force2
=
torch
.
autograd
.
grad
(
energy2
.
sum
(),
coordinates
)[
0
]
energy_diff
=
(
energy1
-
energy2
).
abs
().
max
().
item
()
energy_diff
=
(
energy1
-
energy2
).
abs
().
max
().
item
()
...
...
tests/test_forces.py
View file @
e2e740d0
...
@@ -13,14 +13,16 @@ class TestForce(unittest.TestCase):
...
@@ -13,14 +13,16 @@ class TestForce(unittest.TestCase):
def
setUp
(
self
,
dtype
=
torchani
.
default_dtype
,
def
setUp
(
self
,
dtype
=
torchani
.
default_dtype
,
device
=
torchani
.
default_device
):
device
=
torchani
.
default_device
):
self
.
tolerance
=
1e-5
self
.
tolerance
=
1e-5
self
.
aev_computer
=
torchani
.
SortedAEV
(
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
torch
.
device
(
'cpu'
))
dtype
=
dtype
,
device
=
torch
.
device
(
'cpu'
))
self
.
nnp
=
torchani
.
models
.
NeuroChemNNP
(
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
self
.
aev_computer
)
aev_computer
.
device
)
nnp
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
.
species
)
self
.
model
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
,
nnp
)
def
_test_molecule
(
self
,
coordinates
,
species
,
forces
):
def
_test_molecule
(
self
,
coordinates
,
species
,
forces
):
coordinates
=
torch
.
tensor
(
coordinates
,
requires_grad
=
True
)
coordinates
=
torch
.
tensor
(
coordinates
,
requires_grad
=
True
)
energies
=
self
.
nnp
(
coordinates
,
species
)
energies
=
self
.
model
((
species
,
coordinates
)
)
derivative
=
torch
.
autograd
.
grad
(
energies
.
sum
(),
coordinates
)[
0
]
derivative
=
torch
.
autograd
.
grad
(
energies
.
sum
(),
coordinates
)[
0
]
max_diff
=
(
forces
+
derivative
).
abs
().
max
().
item
()
max_diff
=
(
forces
+
derivative
).
abs
().
max
().
item
()
self
.
assertLess
(
max_diff
,
self
.
tolerance
)
self
.
assertLess
(
max_diff
,
self
.
tolerance
)
...
...
tests/test_ignite.py
View file @
e2e740d0
...
@@ -26,19 +26,16 @@ if sys.version_info.major >= 3:
...
@@ -26,19 +26,16 @@ if sys.version_info.major >= 3:
ds
=
torch
.
utils
.
data
.
Subset
(
ds
,
[
0
])
ds
=
torch
.
utils
.
data
.
Subset
(
ds
,
[
0
])
loader
=
torchani
.
data
.
dataloader
(
ds
,
1
)
loader
=
torchani
.
data
.
dataloader
(
ds
,
1
)
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
device
)
aev_computer
=
torchani
.
SortedAEV
(
dtype
=
dtype
,
device
=
device
)
nnp
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
)
prepare
=
torchani
.
PrepareInput
(
aev_computer
.
species
,
aev_computer
.
device
)
nnp
=
torchani
.
models
.
NeuroChemNNP
(
aev_computer
.
species
)
class
Flatten
(
torch
.
nn
.
Module
):
class
Flatten
(
torch
.
nn
.
Module
):
def
forward
(
self
,
x
):
return
x
.
flatten
()
def
__init__
(
self
,
model
):
model
=
torch
.
nn
.
Sequential
(
prepare
,
aev_computer
,
nnp
,
Flatten
())
super
(
Flatten
,
self
).
__init__
()
batch_nnp
=
torchani
.
models
.
BatchModel
(
model
)
self
.
model
=
model
def
forward
(
self
,
*
input
):
return
self
.
model
(
*
input
).
flatten
()
nnp
=
Flatten
(
nnp
)
batch_nnp
=
torchani
.
models
.
BatchModel
(
nnp
)
container
=
torchani
.
ignite
.
Container
({
'energies'
:
batch_nnp
})
container
=
torchani
.
ignite
.
Container
({
'energies'
:
batch_nnp
})
optimizer
=
torch
.
optim
.
Adam
(
container
.
parameters
())
optimizer
=
torch
.
optim
.
Adam
(
container
.
parameters
())
trainer
=
create_supervised_trainer
(
trainer
=
create_supervised_trainer
(
...
...
torchani/__init__.py
View file @
e2e740d0
...
@@ -2,11 +2,12 @@ from .energyshifter import EnergyShifter
...
@@ -2,11 +2,12 @@ from .energyshifter import EnergyShifter
from
.
import
models
from
.
import
models
from
.
import
data
from
.
import
data
from
.
import
ignite
from
.
import
ignite
from
.aev
import
SortedAEV
from
.aev
import
SortedAEV
,
PrepareInput
from
.env
import
buildin_const_file
,
buildin_sae_file
,
buildin_network_dir
,
\
from
.env
import
buildin_const_file
,
buildin_sae_file
,
buildin_network_dir
,
\
buildin_model_prefix
,
buildin_ensemble
,
default_dtype
,
default_device
buildin_model_prefix
,
buildin_ensemble
,
default_dtype
,
default_device
__all__
=
[
'SortedAEV'
,
'EnergyShifter'
,
'models'
,
'data'
,
'ignite'
,
__all__
=
[
'PrepareInput'
,
'SortedAEV'
,
'EnergyShifter'
,
'models'
,
'data'
,
'ignite'
,
'buildin_const_file'
,
'buildin_sae_file'
,
'buildin_network_dir'
,
'buildin_const_file'
,
'buildin_sae_file'
,
'buildin_network_dir'
,
'buildin_model_prefix'
,
'buildin_ensemble'
,
'buildin_model_prefix'
,
'buildin_ensemble'
,
'default_dtype'
,
'default_device'
]
'default_dtype'
,
'default_device'
]
torchani/aev.py
View file @
e2e740d0
...
@@ -89,6 +89,52 @@ class AEVComputer(BenchmarkedModule):
...
@@ -89,6 +89,52 @@ class AEVComputer(BenchmarkedModule):
self
.
ShfA
=
self
.
ShfA
.
view
(
1
,
1
,
-
1
,
1
)
self
.
ShfA
=
self
.
ShfA
.
view
(
1
,
1
,
-
1
,
1
)
self
.
ShfZ
=
self
.
ShfZ
.
view
(
1
,
1
,
1
,
-
1
)
self
.
ShfZ
=
self
.
ShfZ
.
view
(
1
,
1
,
1
,
-
1
)
def
forward
(
self
,
coordinates_species
):
"""Compute AEV from coordinates and species
Parameters
----------
(species, coordinates)
species : torch.LongTensor
Long tensor for the species, where a value k means the species is
the same as self.species[k]
coordinates : torch.Tensor
The tensor that specifies the xyz coordinates of atoms in the
molecule. The tensor must have shape (conformations, atoms, 3)
Returns
-------
(torch.Tensor, torch.LongTensor)
Returns full AEV and species
"""
raise
NotImplementedError
(
'subclass must override this method'
)
class
PrepareInput
(
torch
.
nn
.
Module
):
def
__init__
(
self
,
species
,
device
):
super
(
PrepareInput
,
self
).
__init__
()
self
.
species
=
species
self
.
device
=
device
def
species_to_tensor
(
self
,
species
):
"""Convert species list into a long tensor.
Parameters
----------
species : list
List of string for the species of each atoms.
Returns
-------
torch.Tensor
Long tensor for the species, where a value k means the species is
the same as self.species[k].
"""
indices
=
{
self
.
species
[
i
]:
i
for
i
in
range
(
len
(
self
.
species
))}
values
=
[
indices
[
i
]
for
i
in
species
]
return
torch
.
tensor
(
values
,
dtype
=
torch
.
long
,
device
=
self
.
device
)
def
sort_by_species
(
self
,
species
,
*
tensors
):
def
sort_by_species
(
self
,
species
,
*
tensors
):
"""Sort the data by its species according to the order in `self.species`
"""Sort the data by its species according to the order in `self.species`
...
@@ -110,28 +156,10 @@ class AEVComputer(BenchmarkedModule):
...
@@ -110,28 +156,10 @@ class AEVComputer(BenchmarkedModule):
new_tensors
.
append
(
t
.
index_select
(
1
,
reverse
))
new_tensors
.
append
(
t
.
index_select
(
1
,
reverse
))
return
(
species
,
*
tensors
)
return
(
species
,
*
tensors
)
def
forward
(
self
,
coordinates_species
):
def
forward
(
self
,
species_coordinates
):
"""Compute AEV from coordinates and species
species
,
coordinates
=
species_coordinates
species
=
self
.
species_to_tensor
(
species
)
Parameters
return
self
.
sort_by_species
(
species
,
coordinates
)
----------
(coordinates, species)
coordinates : torch.Tensor
The tensor that specifies the xyz coordinates of atoms in the
molecule. The tensor must have shape (conformations, atoms, 3)
species : torch.LongTensor
Long tensor for the species, where a value k means the species is
the same as self.species[k]
Returns
-------
(torch.Tensor, torch.Tensor)
Returns (radial AEV, angular AEV), both are pytorch tensor
of `dtype`. The radial AEV must be of shape
(conformations, atoms, radial_length). The angular AEV must
be of shape (conformations, atoms, angular_length)
"""
raise
NotImplementedError
(
'subclass must override this method'
)
def
_cutoff_cosine
(
distances
,
cutoff
):
def
_cutoff_cosine
(
distances
,
cutoff
):
...
@@ -194,24 +222,6 @@ class SortedAEV(AEVComputer):
...
@@ -194,24 +222,6 @@ class SortedAEV(AEVComputer):
self
.
assemble
=
self
.
_enable_benchmark
(
self
.
assemble
,
'assemble'
)
self
.
assemble
=
self
.
_enable_benchmark
(
self
.
assemble
,
'assemble'
)
self
.
forward
=
self
.
_enable_benchmark
(
self
.
forward
,
'total'
)
self
.
forward
=
self
.
_enable_benchmark
(
self
.
forward
,
'total'
)
def
species_to_tensor
(
self
,
species
):
"""Convert species list into a long tensor.
Parameters
----------
species : list
List of string for the species of each atoms.
Returns
-------
torch.Tensor
Long tensor for the species, where a value k means the species is
the same as self.species[k].
"""
indices
=
{
self
.
species
[
i
]:
i
for
i
in
range
(
len
(
self
.
species
))}
values
=
[
indices
[
i
]
for
i
in
species
]
return
torch
.
tensor
(
values
,
dtype
=
torch
.
long
,
device
=
self
.
device
)
def
radial_subaev_terms
(
self
,
distances
):
def
radial_subaev_terms
(
self
,
distances
):
"""Compute the radial subAEV terms of the center atom given neighbors
"""Compute the radial subAEV terms of the center atom given neighbors
...
@@ -482,8 +492,8 @@ class SortedAEV(AEVComputer):
...
@@ -482,8 +492,8 @@ class SortedAEV(AEVComputer):
return
radial_aevs
,
torch
.
cat
(
angular_aevs
,
dim
=
2
)
return
radial_aevs
,
torch
.
cat
(
angular_aevs
,
dim
=
2
)
def
forward
(
self
,
coordinates
_species
):
def
forward
(
self
,
species_
coordinates
):
coordinates
,
species
=
coordinates
_species
species
,
coordinates
=
species
_
coordinates
present_species
=
species
.
unique
(
sorted
=
True
)
present_species
=
species
.
unique
(
sorted
=
True
)
radial_terms
,
angular_terms
,
indices_r
,
indices_a
=
\
radial_terms
,
angular_terms
,
indices_r
,
indices_a
=
\
...
@@ -497,4 +507,4 @@ class SortedAEV(AEVComputer):
...
@@ -497,4 +507,4 @@ class SortedAEV(AEVComputer):
radial
,
angular
=
self
.
assemble
(
radial_terms
,
angular_terms
,
radial
,
angular
=
self
.
assemble
(
radial_terms
,
angular_terms
,
present_species
,
mask_r
,
mask_a
)
present_species
,
mask_r
,
mask_a
)
fullaev
=
torch
.
cat
([
radial
,
angular
],
dim
=
2
)
fullaev
=
torch
.
cat
([
radial
,
angular
],
dim
=
2
)
return
fullaev
return
species
,
fullaev
torchani/models/ani_model.py
View file @
e2e740d0
from
..aev
import
AEVComputer
import
torch
import
torch
from
..benchmarked
import
BenchmarkedModule
from
..benchmarked
import
BenchmarkedModule
...
@@ -9,10 +8,10 @@ class ANIModel(BenchmarkedModule):
...
@@ -9,10 +8,10 @@ class ANIModel(BenchmarkedModule):
Attributes
Attributes
----------
----------
aev_computer : AEVComputer
species : list
T
he
AEV computer
.
C
he
mical symbol of supported atom species
.
output_length : int
output_length : int
The length of output vector
The length of output vector
.
suffixes : sequence
suffixes : sequence
Different suffixes denote different models in an ensemble.
Different suffixes denote different models in an ensemble.
model_<X><suffix> : nn.Module
model_<X><suffix> : nn.Module
...
@@ -26,30 +25,15 @@ class ANIModel(BenchmarkedModule):
...
@@ -26,30 +25,15 @@ class ANIModel(BenchmarkedModule):
the tensor containing desired output.
the tensor containing desired output.
output_length : int
output_length : int
Length of output of each submodel.
Length of output of each submodel.
derivative : boolean
Whether to support computing the derivative w.r.t coordinates,
i.e. d(output)/dR
derivative_graph : boolean
Whether to generate a graph for the derivative. This would be required
only if the derivative is included as part of the loss function.
timers : dict
timers : dict
Dictionary storing the the benchmark result. It has the following keys:
Dictionary storing the the benchmark result. It has the following keys:
aev : time spent on computing AEV.
nn : time spent on computing output from AEV.
derivative : time spend on computing derivative w.r.t. coordinates
after the outputs is given. This key is only available if
derivative computation is turned on.
forward : total time for the forward pass
forward : total time for the forward pass
"""
"""
def
__init__
(
self
,
aev_computer
,
suffixes
,
reducer
,
output_length
,
models
,
def
__init__
(
self
,
species
,
suffixes
,
reducer
,
output_length
,
models
,
benchmark
=
False
):
benchmark
=
False
):
super
(
ANIModel
,
self
).
__init__
(
benchmark
)
super
(
ANIModel
,
self
).
__init__
(
benchmark
)
if
not
isinstance
(
aev_computer
,
AEVComputer
):
self
.
species
=
species
raise
TypeError
(
"ModelOnAEV: aev_computer must be a subclass of AEVComputer"
)
self
.
aev_computer
=
aev_computer
self
.
suffixes
=
suffixes
self
.
suffixes
=
suffixes
self
.
reducer
=
reducer
self
.
reducer
=
reducer
self
.
output_length
=
output_length
self
.
output_length
=
output_length
...
@@ -57,20 +41,19 @@ class ANIModel(BenchmarkedModule):
...
@@ -57,20 +41,19 @@ class ANIModel(BenchmarkedModule):
setattr
(
self
,
i
,
models
[
i
])
setattr
(
self
,
i
,
models
[
i
])
if
benchmark
:
if
benchmark
:
self
.
aev_to_output
=
self
.
_enable_benchmark
(
self
.
aev_to_output
,
'nn'
)
self
.
forward
=
self
.
_enable_benchmark
(
self
.
forward
,
'forward'
)
self
.
forward
=
self
.
_enable_benchmark
(
self
.
forward
,
'forward'
)
def
aev_to_output
(
self
,
aev
,
species
):
def
forward
(
self
,
species
_aev
):
"""Compute output from aev
"""Compute output from aev
Parameters
Parameters
----------
----------
(species, aev)
species : torch.Tensor
Tensor storing the species for each atom.
aev : torch.Tensor
aev : torch.Tensor
Pytorch tensor of shape (conformations, atoms, aev_length) storing
Pytorch tensor of shape (conformations, atoms, aev_length) storing
the computed AEVs.
the computed AEVs.
species : torch.Tensor
Tensor storing the species for each atom.
Returns
Returns
-------
-------
...
@@ -78,6 +61,7 @@ class ANIModel(BenchmarkedModule):
...
@@ -78,6 +61,7 @@ class ANIModel(BenchmarkedModule):
Pytorch tensor of shape (conformations, output_length) for the
Pytorch tensor of shape (conformations, output_length) for the
output of each conformation.
output of each conformation.
"""
"""
species
,
aev
=
species_aev
conformations
=
aev
.
shape
[
0
]
conformations
=
aev
.
shape
[
0
]
atoms
=
len
(
species
)
atoms
=
len
(
species
)
rev_species
=
species
.
__reversed__
()
rev_species
=
species
.
__reversed__
()
...
@@ -88,11 +72,11 @@ class ANIModel(BenchmarkedModule):
...
@@ -88,11 +72,11 @@ class ANIModel(BenchmarkedModule):
for
s
in
species_dedup
:
for
s
in
species_dedup
:
begin
=
species
.
index
(
s
)
begin
=
species
.
index
(
s
)
end
=
atoms
-
rev_species
.
index
(
s
)
end
=
atoms
-
rev_species
.
index
(
s
)
y
=
aev
[:,
begin
:
end
,
:].
reshape
(
-
1
,
self
.
aev_computer
.
aev_length
)
y
=
aev
[:,
begin
:
end
,
:].
flatten
(
0
,
1
)
def
apply_model
(
suffix
):
def
apply_model
(
suffix
):
model_X
=
getattr
(
self
,
'model_'
+
model_X
=
getattr
(
self
,
'model_'
+
self
.
aev_computer
.
species
[
s
]
+
suffix
)
self
.
species
[
s
]
+
suffix
)
return
model_X
(
y
)
return
model_X
(
y
)
ys
=
[
apply_model
(
suffix
)
for
suffix
in
self
.
suffixes
]
ys
=
[
apply_model
(
suffix
)
for
suffix
in
self
.
suffixes
]
y
=
sum
(
ys
)
/
len
(
ys
)
y
=
sum
(
ys
)
/
len
(
ys
)
...
@@ -102,26 +86,3 @@ class ANIModel(BenchmarkedModule):
...
@@ -102,26 +86,3 @@ class ANIModel(BenchmarkedModule):
per_species_outputs
=
torch
.
cat
(
per_species_outputs
,
dim
=
1
)
per_species_outputs
=
torch
.
cat
(
per_species_outputs
,
dim
=
1
)
molecule_output
=
self
.
reducer
(
per_species_outputs
,
dim
=
1
)
molecule_output
=
self
.
reducer
(
per_species_outputs
,
dim
=
1
)
return
molecule_output
return
molecule_output
def
forward
(
self
,
coordinates
,
species
):
"""Feed forward
Parameters
----------
coordinates : torch.Tensor
The pytorch tensor of shape (conformations, atoms, 3) storing
the coordinates of all atoms of all conformations.
species : list of string
List of string storing the species for each atom.
Returns
-------
torch.Tensor
Tensor of shape (conformations, output_length) for the
output of each conformation.
"""
species
=
self
.
aev_computer
.
species_to_tensor
(
species
)
_species
,
_coordinates
,
=
self
.
aev_computer
.
sort_by_species
(
species
,
coordinates
)
aev
=
self
.
aev_computer
((
_coordinates
,
_species
))
return
self
.
aev_to_output
(
aev
,
_species
)
torchani/models/batch.py
View file @
e2e740d0
...
@@ -12,5 +12,5 @@ class BatchModel(torch.nn.Module):
...
@@ -12,5 +12,5 @@ class BatchModel(torch.nn.Module):
for
i
in
batch
:
for
i
in
batch
:
coordinates
=
i
[
'coordinates'
]
coordinates
=
i
[
'coordinates'
]
species
=
i
[
'species'
]
species
=
i
[
'species'
]
results
.
append
(
self
.
model
(
coordinates
,
species
))
results
.
append
(
self
.
model
(
(
species
,
coordinates
)
))
return
torch
.
cat
(
results
)
return
torch
.
cat
(
results
)
torchani/models/custom.py
View file @
e2e740d0
...
@@ -3,7 +3,7 @@ from .ani_model import ANIModel
...
@@ -3,7 +3,7 @@ from .ani_model import ANIModel
class
CustomModel
(
ANIModel
):
class
CustomModel
(
ANIModel
):
def
__init__
(
self
,
aev_computer
,
per_species
,
reducer
,
def
__init__
(
self
,
per_species
,
reducer
,
derivative
=
False
,
derivative_graph
=
False
,
benchmark
=
False
):
derivative
=
False
,
derivative_graph
=
False
,
benchmark
=
False
):
"""Custom single model, no ensemble
"""Custom single model, no ensemble
...
@@ -31,7 +31,8 @@ class CustomModel(ANIModel):
...
@@ -31,7 +31,8 @@ class CustomModel(ANIModel):
raise
ValueError
(
raise
ValueError
(
'''output length of each atomic neural network must
'''output length of each atomic neural network must
match'''
)
match'''
)
super
(
CustomModel
,
self
).
__init__
(
aev_computer
,
suffixes
,
reducer
,
super
(
CustomModel
,
self
).
__init__
(
list
(
per_species
.
keys
()),
suffixes
,
output_length
,
models
,
benchmark
)
reducer
,
output_length
,
models
,
benchmark
)
for
i
in
per_species
:
for
i
in
per_species
:
setattr
(
self
,
'model_'
+
i
,
per_species
[
i
])
setattr
(
self
,
'model_'
+
i
,
per_species
[
i
])
torchani/models/neurochem_atomic_network.py
View file @
e2e740d0
...
@@ -12,10 +12,6 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
...
@@ -12,10 +12,6 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
Attributes
Attributes
----------
----------
dtype : torch.dtype
Pytorch data type for tensors
device : torch.Device
The device where tensors should be.
layers : int
layers : int
Number of layers.
Number of layers.
output_length : int
output_length : int
...
@@ -29,13 +25,11 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
...
@@ -29,13 +25,11 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
The NeuroChem index for activation.
The NeuroChem index for activation.
"""
"""
def
__init__
(
self
,
dtype
,
device
,
filename
):
def
__init__
(
self
,
filename
):
"""Initialize from NeuroChem network directory.
"""Initialize from NeuroChem network directory.
Parameters
Parameters
----------
----------
dtype : torch.dtype
Pytorch data type for tensors
filename : string
filename : string
The file name for the `.nnf` file that store network
The file name for the `.nnf` file that store network
hyperparameters. The `.bparam` and `.wparam` must be
hyperparameters. The `.bparam` and `.wparam` must be
...
@@ -43,8 +37,6 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
...
@@ -43,8 +37,6 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
"""
"""
super
(
NeuroChemAtomicNetwork
,
self
).
__init__
()
super
(
NeuroChemAtomicNetwork
,
self
).
__init__
()
self
.
dtype
=
dtype
self
.
device
=
device
networ_dir
=
os
.
path
.
dirname
(
filename
)
networ_dir
=
os
.
path
.
dirname
(
filename
)
with
open
(
filename
,
'rb'
)
as
f
:
with
open
(
filename
,
'rb'
)
as
f
:
buffer
=
f
.
read
()
buffer
=
f
.
read
()
...
@@ -204,7 +196,7 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
...
@@ -204,7 +196,7 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
raise
NotImplementedError
(
raise
NotImplementedError
(
'''different activation on different
'''different activation on different
layers are not supported'''
)
layers are not supported'''
)
linear
=
torch
.
nn
.
Linear
(
in_size
,
out_size
)
.
type
(
self
.
dtype
)
linear
=
torch
.
nn
.
Linear
(
in_size
,
out_size
)
name
=
'layer{}'
.
format
(
i
)
name
=
'layer{}'
.
format
(
i
)
setattr
(
self
,
name
,
linear
)
setattr
(
self
,
name
,
linear
)
if
in_size
*
out_size
!=
wsz
or
out_size
!=
bsz
:
if
in_size
*
out_size
!=
wsz
or
out_size
!=
bsz
:
...
@@ -219,14 +211,12 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
...
@@ -219,14 +211,12 @@ class NeuroChemAtomicNetwork(torch.nn.Module):
wsize
=
in_size
*
out_size
wsize
=
in_size
*
out_size
fw
=
open
(
wfn
,
'rb'
)
fw
=
open
(
wfn
,
'rb'
)
w
=
struct
.
unpack
(
'{}f'
.
format
(
wsize
),
fw
.
read
())
w
=
struct
.
unpack
(
'{}f'
.
format
(
wsize
),
fw
.
read
())
w
=
torch
.
tensor
(
w
,
dtype
=
self
.
dtype
,
device
=
self
.
device
).
view
(
w
=
torch
.
tensor
(
w
).
view
(
out_size
,
in_size
)
out_size
,
in_size
)
linear
.
weight
.
data
=
w
linear
.
weight
.
data
=
w
fw
.
close
()
fw
.
close
()
fb
=
open
(
bfn
,
'rb'
)
fb
=
open
(
bfn
,
'rb'
)
b
=
struct
.
unpack
(
'{}f'
.
format
(
out_size
),
fb
.
read
())
b
=
struct
.
unpack
(
'{}f'
.
format
(
out_size
),
fb
.
read
())
b
=
torch
.
tensor
(
b
,
dtype
=
self
.
dtype
,
b
=
torch
.
tensor
(
b
).
view
(
out_size
)
device
=
self
.
device
).
view
(
out_size
)
linear
.
bias
.
data
=
b
linear
.
bias
.
data
=
b
fb
.
close
()
fb
.
close
()
...
...
torchani/models/neurochem_nnp.py
View file @
e2e740d0
...
@@ -7,8 +7,7 @@ from ..env import buildin_network_dir, buildin_model_prefix, buildin_ensemble
...
@@ -7,8 +7,7 @@ from ..env import buildin_network_dir, buildin_model_prefix, buildin_ensemble
class
NeuroChemNNP
(
ANIModel
):
class
NeuroChemNNP
(
ANIModel
):
def
__init__
(
self
,
aev_computer
,
from_
=
None
,
ensemble
=
False
,
def
__init__
(
self
,
species
,
from_
=
None
,
ensemble
=
False
,
benchmark
=
False
):
derivative
=
False
,
derivative_graph
=
False
,
benchmark
=
False
):
"""If from_=None then ensemble must be a boolean. If ensemble=False,
"""If from_=None then ensemble must be a boolean. If ensemble=False,
then use buildin network0, else use buildin network ensemble.
then use buildin network0, else use buildin network ensemble.
If from_ != None, ensemble must be either False or an integer
If from_ != None, ensemble must be either False or an integer
...
@@ -46,12 +45,10 @@ class NeuroChemNNP(ANIModel):
...
@@ -46,12 +45,10 @@ class NeuroChemNNP(ANIModel):
models
=
{}
models
=
{}
output_length
=
None
output_length
=
None
for
network_dir
,
suffix
in
zip
(
network_dirs
,
suffixes
):
for
network_dir
,
suffix
in
zip
(
network_dirs
,
suffixes
):
for
i
in
aev_computer
.
species
:
for
i
in
species
:
filename
=
os
.
path
.
join
(
filename
=
os
.
path
.
join
(
network_dir
,
'ANN-{}.nnf'
.
format
(
i
))
network_dir
,
'ANN-{}.nnf'
.
format
(
i
))
model_X
=
NeuroChemAtomicNetwork
(
model_X
=
NeuroChemAtomicNetwork
(
filename
)
aev_computer
.
dtype
,
aev_computer
.
device
,
filename
)
if
output_length
is
None
:
if
output_length
is
None
:
output_length
=
model_X
.
output_length
output_length
=
model_X
.
output_length
elif
output_length
!=
model_X
.
output_length
:
elif
output_length
!=
model_X
.
output_length
:
...
@@ -59,5 +56,5 @@ class NeuroChemNNP(ANIModel):
...
@@ -59,5 +56,5 @@ class NeuroChemNNP(ANIModel):
'''output length of each atomic neural networt
'''output length of each atomic neural networt
must match'''
)
must match'''
)
models
[
'model_'
+
i
+
suffix
]
=
model_X
models
[
'model_'
+
i
+
suffix
]
=
model_X
super
(
NeuroChemNNP
,
self
).
__init__
(
aev_computer
,
suffixes
,
reducer
,
super
(
NeuroChemNNP
,
self
).
__init__
(
species
,
suffixes
,
reducer
,
output_length
,
models
,
benchmark
)
output_length
,
models
,
benchmark
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment